int i = i ^ i 的值是零还是未定义行为?

4
在下面的程序中,输出总是零还是未定义行为?
#include<iostream>

int main()
{
    int i= i ^ i ;
    std::cout << "i = " << i << std::endl;
}

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

4
按位异或,正确的写法。 - Femaref
3
可能是What happens to a declared, uninitialized variable in C? Does it have a value?的重复问题。在C语言中,声明但未初始化的变量将包含未定义的值。 - devnull
6
@KarolyHorvath 好的,这更像是一个合适的语言法律问题(并且这不是那么不相关,因���这是一种常见的汇编/编译器初始化习惯用语),而不是无数个“为什么我的Facebook不能在jQuery中绘制OpenGL?”之类的问题。如果你觉得你不需要了解编程语言的内部工作原理,那么请随意发布一个“这是异或运算,还能做什么,蠢货!”的回答。 - Christian Rau
4
这是一个荒谬的问题,提出者明知这是未定义行为,但却没有给出任何具体细节,比如操作系统、编译器或架构等。 - PP.
2
@PP。我想知道你是从哪里得到的印象,认为OP意识到这是未定义行为。 - Christian Rau
显示剩余13条评论
2个回答

18
int i= i ^ i ;

由于 i 是自动变量(即它在自动存储期内声明),因此它尚未(静态地)初始化,但您正在读取其值以进行初始化(动态地)。因此,您的代码会引发未定义行为。

如果您将 i 声明为命名空间级别或使用 static,那么您的代码将是正确的:

  • 命名空间级别

int i = i ^ i; //declared at namespace level (static storage duration)

int main() {}
  • 或者将其定义为本地静态变量:

    int main()
    {
         static int i = i ^ i; //static storage duration
    }
    
  • 这两个代码都没问题,因为变量 i 是静态初始化的,它被声明在 静态 存储期中。


    2
    @G_G:严谨地讲,它可以做任何事情 - Nawaz
    6
    将垃圾与垃圾进行异或操作不一定会产生零。在某些体系结构上,即使编译器没有基于您不会做任何愚蠢的事情(如故意调用未定义行为)的假设进行优化,这实际上可能会导致令人讨厌且难以调试的崩溃。 - user2357112
    4
    @G_G:我想再举一个例子,未初始化的布尔类型变量既不是真也不是假。它可以是任何值,规范称其状态为“未确定”。请参考这个问题:https://dev59.com/RG445IYBdhLWcg3wZJiw。希望这能帮助你理解这个问题。 - Nawaz
    5
    @G_G和Najzero:这里的问题是,正如Nawaz指出的那样,从未初始化的变量中读取数据是未定义行为。因此,标准不会保证两次连续的读取会产生相同的值(当然,我们在这里纠结于微末之处...但这就是标准的规定)。甚至没有保证它实际上会读取值,它可能会抛出异常、段错误或其他任何错误。 - syam
    2
    @G_G:NAT的事情是指Itanium,而NAT XOR NAT是NAT,不是零。在Itanium上,这是明确定义的行为。 - MSalters
    显示剩余7条评论

    5

    未定义行为。未初始化的垃圾实际上不一定是给定类型的未知但有效的值。在某些体系结构上(特别是Itanium),未初始化的垃圾实际上可能会在您尝试使用它时导致崩溃。有关IA64的Not a Thing如何让您混淆,请参见http://blogs.msdn.com/b/oldnewthing/archive/2004/01/19/60162.aspx


    2
    @G_G:它不一定是32位或64位的组合!实际上,它可以有一个秘密的第65个“引爆一切”的位。详情请见链接。 - user2357112
    2
    @G_G:甚至不能保证是32位或64位。著名的Cray超级计算机将int实现为浮点值,小数部分设置为零。现在想象一下,如果你拿垃圾数据,然后将整数部分与自身进行异或运算,会发生什么?小数部分的垃圾数据会怎样处理?! - MSalters
    就是我想写的。没有人说32位值的整数必须存储在32位上。它可以有很多额外的隐藏标志。它们不会被异或,因为它们不是“用户数据”,但是由于未初始化,它们可能表现异常。编辑:哇,整数转换为浮点数?我得去了解一下。 - quetzalcoatl
    @user2357112 加一分,因为你知道“炸掉一切”的秘密。不出奇迹,Itanium从未成功起飞。 :) - user4815162342
    3
    为什么一个整数异或运算会将小数部分设为零?这不是整数异或运算的工作方式。它甚至不会触及小数部分。 - MSalters
    显示剩余3条评论

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接