简体   繁体   English

请解释为什么这个简单的C ++(Qt)代码如此奇怪

[英]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). 从评论中可以看到,我希望函数传递一个包含{2,3}的数组,但是实际上传递了{0,3} (由调试器检查,在Linux上使用gcc 6)。

In general, the order of evaluation of different subexpressions of an expression is unspecified in C++. 通常,在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. 换句话说,编译器发出先评估test_map[1]然后再评估testFunc调用的代码是完全合法的。 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 . 当然,如果发生这种情况,那么在评估参数test_map.value(1, 2)test_map[1]已经在映射中创建了映射1 : 0 ,因此test_map.value(1, 2)返回存在的映射值0而不是使用提供的默认值2

Note that in this case, the above only holds in C++14 and earlier. 请注意,在这种情况下,以上内容仅适用于C ++ 14和更早版本。 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. 从C ++ 17开始,确保对内置赋值运算符的右侧进行评估,然后再评估其左侧,因此在C ++ 17中,您看到的行为无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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