简体   繁体   中英

Please explain why this simple C++(Qt) code works so strange

Please explain the behavior of this code:

#include <QCoreApplication>
#include <QMap>

int testFunc(const QList<int>& data)
{
    // my debugger says data is {0,3}, but I expected {2, 3}. What happened?!
    return data.at(0);
}

int main(int argc, char* argv[])
{
    QCoreApplication a(argc, argv);

    QMap<int, int> test_map;
    int x = test_map.value(1, 2); // // x is 2 (OK)
    test_map[1] = testFunc(
            {
            test_map.value(1, 2), // 2
            3
            });

    return 0;
}

As you can see from the comments, I expect the function to be passed an array containing {2,3} , but {0,3} is actually passed (checked by a debugger, on Linux using gcc 6).

In general, the order of evaluation of different subexpressions of an expression is unspecified in C++. In this particular case, this means that it's not specified which side of the assignment operator is evaluated first.

In other words, it's perfectly legal for the compiler to emit code that will evaluate test_map[1] first and only then evaluate the testFunc call. Of course, if that happens, then by the time the argument test_map.value(1, 2) is evaluated, test_map[1] has already created the mapping 1 : 0 in the map, so test_map.value(1, 2) returns this existting mapped value of 0 instead of using the supplied default of 2 .

Note that in this case, the above only holds in C++14 and earlier. Since C++17, the right-hand side of a built-in assignment operator is guaranteed to be evaluated before the left-hand side, so in C++17, the behaviour you're seeing shouldn't be valid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM