-1

假设我想打印一些值。我假设如果我的有符号变量超过 from TMinand TMax(在这种情况下,使用 4 字节 int,0x7FFFFFFFasTmax0x80000000as 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)
4

4 回答 4

2

首先,让我告诉你,(有符号的)整数溢出会调用未定义的行为

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

只是为了澄清,即使

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

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

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

转换为整数类型或从整数类型转换会产生一个超出可表示范围的值。

于 2016-02-01T20:01:11.103 回答
1

试图调用整数溢出是未定义的行为。根据标准,在这种情况下,任何事情都可能发生,包括表面上出现的非溢出。这个输出是无趣且无关紧要的。

可能是您的编译器对其进行了优化。可能是您的系统拒绝以这种方式使用,可能是一袋大米掉在中国引起了蝴蝶效应,导致了这种情况。它只是定义了那里发生的事情。

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

于 2016-02-01T20:07:31.090 回答
1

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

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

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

0x80000000-1是一个无符号类型,因为它0x80000000首先适合无符号类型,可能unsigned具有2147483648u. 2147483648u - 1--> 2147483647u

0x7FFFFFFF+1是一个有符号类型,因为它0x7FFFFFFF首先适合有符号类型,可能int具有 的值INT_MAX
int+ int-->int INT_MAX + 1--> 溢出。


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

于 2016-02-01T20:12:25.343 回答
1

C 对于数字异常有点不一致。

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

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

unsigned int i = UINT_MAX;

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

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

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

于 2016-02-01T21:49:41.340 回答