In C++, is there a defined order of operations when assigning an expression into an object when the expression involves that object?

Viewed 78

Consider the following C++ code that uses Qt's container class QMap:

#include <QMap>
#include <iostream>

QMap<int, int> myMap;

int count() {
    return myMap.size();
}

int main() {
    myMap[0] = count();
    std::cout << myMap[0] << std::endl;
    return 0;
}

Depending on whether myMap has a new entry created in it before or after count() is executed, this code's output will be either 1 or 0 respectively.

Does the output of this code depend on the implementation of QMap? Or does the C++ specification make any guarantees about when count() will be executed in relation to QMap::operator[]? Or could the result be undefined and this is a situation that's best avoided?

I ask because I had an essentially identical situation in a program I was working on. When I compiled the program in Windows and ran it using the stock Qt 5.5.1 DLLs, the result was 0. However, when I ran it using a different set of Qt 5.5.1 DLLs that had been compiled from source, the result was 1. It was an awfully confusing bug that took me a little while to track down, particularly since I got different results depending on where I ran the executable!

I'm hoping that I can understand how there was two different behaviors for the same program so that I might be able to avoid bugs like this in the future.

3 Answers
Related