C++ INTA。。。;(a==a)失败了?

C++ INTA。。。;(a==a)失败了?,c++,C++,如果我们将float和double type设置为NaN,则它们不等于任何内容,包括本身 int是否会发生这种情况?NaN是a==a返回false的唯一值 并且int不支持NaN值。所以不,你不能在int中出现这种情况 另一个注意事项是,要检查值是否为NaN,应使用isnan()而不是a==a 关于同一主题: 如果将未初始化的变量与自身进行比较,任何事情都可能发生。这毕竟是未定义的行为。对于初始化的int变量,这是不可能发生的 请注意,未显式初始化的命名空间范围、类静态和函数静态int变量

如果我们将float和double type设置为NaN,则它们不等于任何内容,包括本身

int是否会发生这种情况?

NaN是
a==a
返回false的唯一值

并且
int
不支持NaN值。所以不,你不能在
int
中出现这种情况

另一个注意事项是,要检查值是否为NaN,应使用
isnan()
而不是
a==a


关于同一主题:

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

请注意,未显式初始化的命名空间范围、类静态和函数静态int变量的值为0。那么他们就不会比较平等了


我刚刚用叮当声测试过:

int main() {
  int x;
  return (x == x);
}
使用-O1编译时,返回0,因为优化器可以假定x没有稳定值

GCC对上述内容更宽容,返回1。以下内容也使GCC返回0(如果允许您选择,显然不执行分支会更便宜):


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

在比较普通初始化的int变量时,不会发生这种情况

在引用硬件寄存器时,可能会发生int比较,例如:

*timeRegister == *timeRegister

当您将volatile int变量与在比较过程中由信号处理程序修改的自身进行比较时,也可能发生这种情况。

如何取决于编译器的优化;看看拆卸。如果它使用二进制“and”,则检查标志,如果a为零,则在失败后检查标志。

否。浮点数的比较是这样定义的,与任何数字比较的NaN将返回false。无论如何,对于整数,还有另一个公式:

unsigned int a = -1;
if (a == (unsigned char) a) { //returns false
(...)
ZF = !(a ^ b);
对于a的任何可能值,这都是真的


编辑:在GCC上,使用任意-O标志,比较结果就不符合真值。

如果比较未初始化的变量,这是完全可能的

<>在C++语言中,未初始化变量不能保证保持稳定值。理论上,使用未初始化的值进行操作会产生未定义的行为。实际上,多次读取同一未初始化变量的值很容易导致读取不同的值。最明显的实际原因是变量被优化为某个CPU寄存器

为了有效地管理有限数量的CPU寄存器,优化编译器使用变量的值生命周期的概念进行操作。值生存期本质上是变量保持特定稳定值的时间段。值生存期从初始化变量开始,到重新初始化为另一个值(或最后一次访问变量)结束。在“值生命周期”内,值必须稳定,因此CPU寄存器不能用于其他目的(或者每次用于其他目的时都必须小心保存和恢复)

在值生存期之外,不需要保留寄存器的值,因此它可以自由地用于其他目的。因此,如果某个变量由CPU寄存器表示,但未初始化(即,如果其值生命周期尚未开始),其观察值可能会发生完全不可预测的变化,每次读取该变量时都会产生新值,因为相应CPU寄存器的内容会因一些不相关的原因而发生变化


这可能很容易导致
a==a
使用未初始化的
a
计算为
false
。当然,当两个读数看起来如此“接近”在一起时,看到这种情况是相当令人惊讶的。但它仍然可能发生。这种行为是完全标准的。标准不保证初始化变量的稳定性。

< P>虽然它确实是不寻常的,但是C++允许<代码> int >代码> <代码>楠< /C> > < /P> 首先,
int
可以存储除数值以外的信息。§3.9.1/1:

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

然后,对于任何类型,
numeric\u limits::has\u quiet\u NaN
has\u signaling\u NaN
都不要求为
false
。§18.2.1.2/34-36:

34如果类型具有 代表安静 (非信号)“不是数字。”

35适用于所有浮点 类型

36对所有人都是如此 专业是什么?iec559= 错

“对所有浮点类型都有意义”有点麻烦,因为它可能会使值变得毫无意义,但这肯定是一种推断

如果
numeric\u limits::has\u quiet\u NaN==true
,则
numeric\u limits::quiet\u NaN()
返回该值

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

因为C++20,答案(对于初始化变量)是否定的

如建议所述,符号整数以前允许各种值表示,包括“存在一个非常值,陷阱,额外填充位,和[0个积分负零点”)(Hence Potatoswatter的回答,理论上,楠值对于int是可能的)。但是,实际上,运行C++的每一个机器都使用一个有符号整数的“正规”二的补码表示

<支持该建议,C++标准委员会决定规范两个补充,不允许超常值。现在,有符号整数的值表示是固定的,而在整数内。
ZF = !(a ^ b);
static const bool has_quiet_NaN;