【问题标题】:Value of int i = i ^ i ; Is it always zero or undefined behavior?int i = i ^ i 的值;它总是零或未定义的行为吗?
【发布时间】:2013-07-03 09:00:59
【问题描述】:

在下面的程序中,输出总是为零,还是未定义的行为?

#include<iostream>

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

使用 gcc 4.8.0 编译成功,输出为 0。

【问题讨论】:

  • 按位XOR,正确。
  • @KarolyHorvath 好吧,与其说是一百万个“为什么我Facebook 没有在 jQuery 中绘制 OpenGL?”-问题。如果您觉得您不需要了解编程语言的内部工作原理,请随意发布 “这是 XOR,它还能做什么,愚蠢!”-答案。
  • 这是一个荒谬的问题,完全知道它是未定义的行为,但没有应用任何细节,例如哪个操作系统,哪个编译器,或者它将为哪个架构编译。
  • @PP。我想知道你从哪里得到的印象是 OP 知道这是未定义的行为。

标签: c++ language-lawyer


【解决方案1】:

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

【讨论】:

  • “给定类型”?我们正在谈论一个 int 类型! 32 位或 64 位的每个组合都是 int 类型的有效值
  • @G_G:不一定是 32 位或 64 位的组合!它实际上可以有一个秘密,第 65 个“炸毁一切”位。详情见链接。
  • @G_G:甚至不能保证是 32 位或 64 位。著名的 Cray 超级计算机将 int 实现为浮点值,小数部分设置为零。现在想象一下,如果你拿垃圾,然后将整数部分与自身进行异或,会发生什么。部分垃圾会发生什么?!
  • 正是我想写的。没有人说 32 位值的整数必须存储在 32 位上。它可以有大量额外的隐藏标志。它们不会得到 XOR'red,因为它们不是“用户数据”,但未初始化,它们可能行为不端。编辑:哇。整数转换为浮点数?我得读一读。
  • @G_G:为什么 integer XOR 会将小数部分设置为零?这不是整数 XOR 的工作方式。它甚至不涉及小数部分。
【解决方案2】:
int i= i ^ i ;

由于i 是一个自动变量(即,它在自动 存储期限内声明),它不是(静态)初始化但你是读取它的值来初始化它(动态地)。所以你的代码会调用未定义的行为。

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

  • 命名空间级别

    int i = i ^ i; //declared at namespace level (static storage duration)
    
    int main() {}
    
  • 或者在本地定义为static:

    int main()
    {
         static int i = i ^ i; //static storage duration
    }
    

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

【讨论】:

  • @G_G:不。学究式地说,它可以做任何事情
  • 用垃圾异或垃圾不必产生零。它实际上会在某些架构上产生令人讨厌的、难以调试的崩溃,即使编译器没有在假设您不会做任何像故意调用未定义行为那样愚蠢的事情的情况下进行优化。
  • @G_G:我还想补充一点,例如,未初始化的bool 既不是true,也不是false。它可以是任何东西,规范称其状态为indeterminate。看到这个问题:stackoverflow.com/questions/4879045/…。我希望这可以帮助您理解这里的问题。
  • @G_G 和 Najzero:正如 Nawaz 指出的那样,这里的问题是,从未初始化的变量中读取的是 UB。因此,标准提供no保证两次连续读取将产生相同的值(当然,我们在这里分裂头发......但这正是标准的编写方式)。甚至不能保证它会实际读取值,它可能会抛出异常或段错误或其他任何东西。
  • @MWid:规范确实在整个文本中使用了短语“未初始化”。请不要通过重新定义来混淆其他人。该语言已经庞大而复杂!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
相关资源
最近更新 更多