C积分溢出?

fie*_*sor 8 c c89

看看这个.编译器抱怨我有一个整数溢出,但是当我查看C89标准的整数提升规则以及该表达式中的值时,我觉得没有溢出.

rutski@imac:~$ cat test.c 
#include <stdio.h>
#include <inttypes.h>

const uint32_t value =
    (0x7F-0x00 + 1) * (256 + 256*256 + 256*256*256) +
    (0xDF-0xC2 + 1) * (256 + 256*256 + 256*256*256);

int
main(void)
{
    printf("value = %"PRIu32"\n", value);
    return 0;
}
rutski@imac:~$ gcc -std=c89 -pedantic -Wall -Wextra test.c
test.c:5: warning: integer overflow in expression
test.c:6: warning: integer overflow in expression
test.c:6: warning: overflow in constant expression
rutski@imac:~$ ./a.out 
value = 2661195264
rutski@imac:~$ 
Run Code Online (Sandbox Code Playgroud)

此外,谷歌确认2661195264的答案是该表达式的正确值!(见此链接)

那么,当整数溢出时程序如何产生正确的值呢?更重要的是,该表达式中的整数溢出是如何开始的?

Ste*_*non 14

(0x7F-0x00 + 1) * (256 + 256*256 + 256*256*256)
Run Code Online (Sandbox Code Playgroud)

有价值2155905024; 最大可表示签署 32位int2147483647,所以你确实产生了溢出.它碰巧给了你预期的结果(你很幸运).

请注意,您的整个初始化程序都有签名类型(int特定类型),因为没有文字后缀.表达式被计算为signed int,然后将结果值转换为无符号整数.

  • ...并注意`int`只需要16位,所以即使`256*256`也可能是溢出.您可以通过对每个常量使用"256UL"而不是"256"来纠正此问题. (2认同)