我知道
signed int
溢出在 C 中未定义。
我理解这是因为结果数字是不可预测的,但它仍然是一个数字。
但是,此代码的行为并不像溢出操作的结果是 int 数字:
#include<stdio.h>
int main ()
{
int i,m=-727379968,w=1,n;
for (i=1;i<=12;i++)
w*=10;
n=w;
printf("sizeof(int)=%d\n",(int)sizeof(int));
printf ("m=%d n=%d m-n=%d (1<m)=%d (1<n)=%d (m==n)=%d \n", m,n, m-n, 1<m, 1<n,m==n);
return (0);
}
使用gcc版本11.4.0无优化:
sizeof(int)=4
m=-727379968 n=-727379968 m-n=0 (1<m)=0 (1<n)=0 (m==n)=1
这样就可以了。
与
gcc -O2
:
sizeof(int)=4
m=-727379968 n=-727379968 m-n=0 (1<m)=0 (1<n)=1 (m==n)=0
这是错误的。
为什么1小于负数?
为什么差值为0时
m
和n
不相等?
我预计在赋值
n=w
之后,n
中有一些int值。但我不明白结果。
优化器已删除比较
1 < n
和 m == n
并将其替换为已知值。
优化器假设未定义的行为永远不会发生,这意味着它忽略了溢出的可能性。因此它“知道”多次将 1 乘以 10 会得到一个大于 1 的值。因此,
1 < n
始终为真。由于 m
是负数,因此 m == n
永远不可能为真。