没有得到整数溢出

Not getting Integer Overflow

假设我想打印一些值。我假设如果我的签名变量超过 TMinTMax 我应该得到整数溢出(在这种情况下,使用 4 字节 int,0x7FFFFFFF 作为 Tmax0x80000000 as Tmin) 但在这些示例中,我没有得到我期望的结果(在评论中解释):

// Tmax = 0x7FFFFFFF == 2147483647 
// Tmin = 0x80000000 == -2147483648 
printf("1- overflow test: %d\n", 0x7FFFFFFF+1 ); // overflow - how compiler finds out it's a signed value, not an Unsigned one
printf("2- overflow test: %d\n", 0x80000000-1 ); // in contrast, why I am not getting an integer overflow here
printf("3- overflow test: %d\n", (int) 0x80000000-1 ); // overflow (Expected)
printf("4- overflow test: %d\n",(int) (0x7FFFFFFF+1)); // overflow (Expected)

首先,让我告诉你,(有符号)整数溢出调用undefined behavior

在那种情况下,任何事情都有可能发生。您既不能相信也不能证明具有 UB 的代码的输出。

澄清一下,甚至

printf("2- overflow test: %d\n", 0x80000000-1 );

是UB。虽然 0x80000000-1unsigned 并且本身不是溢出,但使用 %d 会导致类型不匹配,这在技术上会导致 UB。

关于未定义的行为,来自C11,附件§J.2,

Conversion to or from an integer type produces a value outside the range that can be represented.

尝试调用整数溢出是未定义的行为。按照标准,在这种情况下,任何事情都可能发生,包括外在出现的非溢出。此输出的内容无趣且无关紧要。

可能是你的编译器优化掉了。可能是你的系统拒绝以这种方式使用,也可能是一袋米落在中国造成了蝴蝶效应,导致了这种情况。它没有定义那里发生的事情。

也可能是您的系统决定它的整数更大。 c 中仅规定了整数大小的下限(2 字节)(标准计算机通常至少为 4)。您的系统可能有 8 字节整数,甚至更大。

OP 并不总是遇到有符号整数溢出 - 这是未定义的行为。

以下是无符号数学,因为 0x80000000 可能是无符号整数。十六进制常量是最先适合的类型int, unsigned, long, unsigned long, ...

printf("2- overflow test: %d\n", 0x80000000-1 );

0x80000000-1 是无符号类型,因为 0x80000000 首先适合无符号类型,可能 unsigned 的值为 2147483648u2147483648u - 1 --> 2147483647u.

0x7FFFFFFF+1 是有符号类型,因为 0x7FFFFFFF 首先适合有符号类型,可能 int 的值为 INT_MAX.
int + int --> int and INT_MAX + 1 --> 溢出.


OP说“0x80000000 as Tmin”肯定是个误会。在C中,对于32位的int/unsigned0x80000000是一个十六进制常量,其值为2147483648。对于 OP,Tmin 更有可能 -INT_MAX - 1.

C 在数字异常方面有点不一致。

有一些您可以做的事情几乎总是会导致问题。如果除以 0,您的程序通常会严重崩溃,就像您访问了一个无效指针一样。

您可以做一些保证不会引起问题的事情。如果你说

unsigned int i = UINT_MAX;

然后加1,保证回绕到0。

还有很多行为是未定义或未指定的。有符号整数溢出就是其中之一。严格来说它是未定义的(任何事情都可能发生,你不能依赖它)。实际上,大多数计算机都悄悄地循环,就像无符号算术一样。

现在,我所说的一切都是关于程序的 运行 时间行为,但在这个问题的已发布代码片段中,所有算术运算都发生在编译时。编译时算法主要根据与 运行-time 相同的规则运行,但并非总是如此。现代编译器往往会警告您有问题的编译时算法(我的 gcc 副本会针对发布的片段发出三个警告),但并非总是如此。