int a; ...; (a == a)失败了吗?

MBZ*_*MBZ 7 c++

如果我们将floatdouble类型设置为NaN,则它们不等于包括它们在内的任何东西.int
会发生这样的事吗?

Joh*_*itb 14

如果将未初始化的变量与自身进行比较,则可能发生任何事情.毕竟是未定义的行为.对于初始化的int变量,这不可能发生.

请注意,未显式初始化的namespace-scope,class-static和function-static int变量的值为0.然后它们不会比较相等.


我刚刚和Clang一起测试过:

int main() {
  int x;
  return (x == x);
}
Run Code Online (Sandbox Code Playgroud)

使用-O1编译时,返回0,因为允许优化器假定x没有稳定值.

GCC对上述内容更加宽容,返回1.以下内容使GCC也返回0(显然,如果您可以选择,那么分支会更便宜):

int main() {
  int x;
  if(x == x) {
    return 1;
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

最后,结果不仅取决于CPU执行代码,还取决于工具链中的任何其他内容.

  • valdo:你错了,因为你正在考虑处理器,忘记了编译器.当然存在*真正的*编译器,它们将优化代码,使得未初始化的整数与其自身的比较可能不会总是产生与比较返回true时相同的结果. (6认同)
  • @slashmais完全取决于实现.某些处理器具有特殊位,当在操作中使用时会产生另一个特殊值.没有初始化的变量可以设置这样的位并且与它们相比时产生特殊值.ia64的NaT就是这样一个例子. (4认同)
  • @MBZ:将unitialized int与自身进行比较是未定义的行为.他们可以比较相同,他们可以比较不平等.他们可以格式化你的硬盘.他们可以召唤克苏鲁.任何使用未定义的行为本质上都是一个错误.未定义的行为永远不会起作用 - 它似乎*似乎*起作用. (4认同)
  • 它也是语义[由LLVM IR声明](http://llvm.org/docs/LangRef.html#undefvalues):"这个例子指出两个undef操作数不一定相同.这对人们来说可能是令人惊讶的(并且还匹配C语义),他们认为"X ^ X"总是为零,即使X是undef." 我认为这意味着,如果clang编译你的代码,并且LLVM优化器会突破它,你应该准备好`x == x`来产生错误. (2认同)

Pot*_*ter 5

尽管这肯定是不寻常的,但C ++确实可以int做到NaN

首先,int除了数字值外,还可以存储信息。§3.9.1/ 1:

对于字符类型,对象表示的所有位都参与值表示。对于无符号字符类型,值表示形式的所有可能的位模式均表示数字。这些要求不适用于其他类型。

然后,numeric_limits<int>::has_quiet_NaN并且has_signaling_NaN不需要false为任何类型。§18.2.1.2/ 34-36:

static const bool has_quiet_NaN;
Run Code Online (Sandbox Code Playgroud)

34如果类型具有一个安静(无信号)“不是数字”的表示,则为真。

35对所有浮点类型有意义。

36对于is_iec559!= false的所有专业都应为true。

“对所有浮点类型有意义”有点麻烦,因为它打开了该值可能毫无意义的可能性,但这肯定是一种推断。

如果为numeric_limits<int>::has_quiet_NaN == true,则numeric_limits<int>::quiet_NaN()返回这样的值。

显然,这不是您应该在代码中担心的事情。