gpt4 book ai didi

c++ - 在 C++ 中,当表达式涉及该对象时,将表达式分配给对象时是否有定义的操作顺序?

转载 作者:太空狗 更新时间:2023-10-29 20:21:16 24 4
gpt4 key购买 nike

考虑以下使用 Qt 容器类 QMap 的 C++ 代码:

#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;
}

根据 myMap 是否在执行 count() 之前或之后在其中创建了一个新条目,此代码的输出将是 10

这段代码的输出是否依赖于QMap的实现?或者 C++ 规范是否对 count() 何时执行与 QMap::operator[] 相关的任何保证?或者结果可能是未定义的,这是最好避免的情况?

我问是因为我在我正在处理的程序中遇到了基本相同的情况。当我在 Windows 中编译该程序并使用常用 Qt 5.5.1 DLL 运行它时,结果为 0。但是,当我使用从源代码编译的另一组 Qt 5.5.1 DLL 运行它时,结果是 1。这是一个非常令人困惑的错误,我花了一些时间来追踪,特别是因为我根据运行可执行文件的位置得到了不同的结果!

我希望我能理解为什么同一个程序会有两种不同的行为,这样我以后就可以避免这样的错误。

最佳答案

你的问题:

myMap[0] = count();

整个赋值是一个表达式,而对count() 的调用是一个子表达式。表达式和子表达式之间没有序列点

这不是关于评估顺序,而是关于副作用的顺序。赋值有一个副作用,在这种情况下,它会向您的QMap 添加一个新元素。只有在序列点,您才能保证序列点之前的代码产生的所有副作用都已完成。

函数调用一个序列点,但它介于函数参数的计算和实际调用之间——与返回值无关。由于您在这里没有任何参数,因此它不适用于这种情况。

所以是的,这是未定义的行为,你应该避免它。作为引用,here's a quite exhaustive answer on the topic of sequence points .


解决方案当然很简单:使用两个单独的语句。语句的结尾 (;) 始终是一个序列点。

关于c++ - 在 C++ 中,当表达式涉及该对象时,将表达式分配给对象时是否有定义的操作顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44980305/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com