int i = i ^ i的值; 它总是零或未定义的行为?

Khu*_*hid 4 c++ language-lawyer

在以下程序中,输出始终为零或未定义的行为?

#include<iostream>

int main()
{
    int i= i ^ i ;
    std::cout << "i = " << i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

用gcc 4.8.0这段代码编译成功,输出为0.

Naw*_*waz 18

int i= i ^ i ;
Run Code Online (Sandbox Code Playgroud)

由于i是自动变量(即它在声明自动存储时间),它是不是(静态)初始化但你它的值初始化(动态).所以你的代码会调用未定义的行为.

如果你i在命名空间级别或者声明static,那么你的代码就可以了:

这两个代码都很好,因为它i静态初始化的,因为它是在静态存储持续时间中声明的.

  • 使用垃圾对垃圾进行异或运输不必产生零.它实际上可以在某些体系结构上产生令人讨厌的,难以调试的崩溃,即使编译器没有在假设您不会像故意调用未定义的行为那样愚蠢的情况下进行优化. (6认同)
  • @G_G和Najzero:这里的问题是,正如Nawaz指出的那样,从未初始化的变量读取是UB.因此,该标准提供**不保证两个连续读取将产生相同的值(当然,我们在这里分裂头发......但这只是标准的编写方式).甚至没有保证它实际上会读取值,它可能会抛出异常或段错误等等. (5认同)
  • @G_G:作为一个例子,我还想补充一个未初始化的`bool`既不是'true`,也不是'false`.它可能是任何东西,规范称其状态为"不确定".请参阅此问题:http://stackoverflow.com/questions/4879045/fun-with-uninitialized-variables-and-compiler-gcc.我希望这可以帮助您理解这里的问题. (4认同)
  • @G_G:不,小说,它可以做任何**. (2认同)
  • @MWid:规范确实在整个文本中使用了"未初始化"这个短语.请不要通过重新定义来混淆他人.语言已经庞大而复杂! (2认同)
  • @G_G:NAT是Itanium,NAT XOR NAT是NAT,而不是零.在Itanium上,这是明确定义的行为. (2认同)

use*_*ica 5

未定义的行为.未初始化的垃圾实际上不必是给定类型的未知但有效的值.在某些体系结构(特别是Itanium)上,当您尝试使用它时,未初始化的垃圾实际上会导致崩溃.请参阅http://blogs.msdn.com/b/oldnewthing/archive/2004/01/19/60162.aspx,了解IA64的Not Thing如何搞砸你.

  • @G_G:为什么**整数**XOR将小数部分设为零?这不是整数XOR的工作原理.它甚至没有触及分数部分. (3认同)
  • @G_G:它不必是32位或64位的组合!它实际上可以有一个秘密,第65次"炸毁一切"位.请参阅链接了解详情 (2认同)
  • @G_G:甚至不能保证是 32 位或 64 位。著名的 Cray 超级计算机将 `int` 实现为浮点值,小数部分设置为零。现在想象一下,如果你取垃圾,并将整数部分与其自身进行异或会发生什么。部分垃圾会发生什么?! (2认同)