c++ - 未定义的行为或误报

标签 c++ gcc g++ gcc-warning

我(基本上)在野外遇到过以下情况

x = x = 5;

显然在早期版本的 gcc 下编译干净(在 gcc 4.5.1 下生成警告)。据我所知,警告是由 -Wsequence-point 生成的。所以我的问题是,这是否违反了标准中关于在序列点之间操作变量的措辞(即,根据规范,它是未定义的行为),或者这是 gcc 误报(即,它是根据规范定义的行为)?序列点的措辞有点难以理解。

我说本质上是因为我实际遇到的(用更大的表达方式)是

x[0][0] = x[0][0] = 5;

但我不认为这对警告有重要意义(如果这是关键,请纠正我,而不是我认为的问题的症结所在)。

最佳答案

假设 x 是内置类型,它将两次赋值给 x 而没有中间序列点,这就是您需要知道的全部内容。两个赋值具有相同的值 (5),并且理论上可以优化为单个赋值(如果 x 不是易变的)这一事实既不存在也不存在。

至少,这就是我在标准中解释“修改”的方式——分配一个值,不管它是否碰巧与旧值相同。同样,我认为,放弃 const 并分配给 const 对象是 UB,无论您分配的值是否恰好等于先前的值。否则,如果实现想要将字符串文字放入 ROM 以防止在这种情况下出现页面错误,那么所有内存写入都会产生巨大的开销,并且我们通过检查知道编译器不会发出该代码。

一个更令人兴奋的例子是 x[0][0] = x[0][i] = 5;,如果(并且仅当) i == 0 时,定义的行为以i 的值为条件。

我不太明白为什么编译器会在这两种情况下做任何意想不到的事情,但我缺乏想象力也是无关紧要的:-)

ablenky 说的对。如果您在某些不能使用两个语句的上下文中,可以改为编写 x[0][0] = 5, x[0][i] = 5。在您给定的两种情况下,只需放弃冗余分配即可。

关于c++ - 未定义的行为或误报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4129239/

相关文章:

c++ - 在 C++ 中将数字转换为英文(1-99)

linux - 如何更改 GCC 版本

linux - gcc 4.8.2 没有可识别的调试信息

c++ - 使用 g++ 中设置的 -O2 执行 std::string 分配时无效 free

c++ - g++ 是否不从它存在的第一个包含路径中获取头文件?

c++ - Goto 无法正常工作 C++

c++ - C++ 中的指针参数接收地址?

c++ - 数组和普通指针与 std::unique_ptr 的区别

c++ - 如何使用 Genlex 构建 OCaml 源代码

c++ - 如何在 emacs 中使用 gcc-code-assist?