为什么下面的程序会发生溢出?

Why may an overflow occur in the following program?

void main () {
  int i;
  if (i < 0) { i = -i; };
}

谁能帮我理解为什么上面的程序会出现溢出?

可能会出现溢出,因为二进制补码中整数表示的范围不是对称的:可以表示的最小负数的大小是可以表示的最大正数的大小加1。例如,在 32 位系统上,值为 -2,147,483,6482,147,483,647。这就是为什么否定 -2,147,483,648 会导致溢出:否定的结果,正值 2,147,483,648,不能用相同大小的 int 表示。

请注意,这个问题的反面是不正确的:否定一个正数不会导致溢出:

if (i > 0) { i = -i; } // No overflow here

整数溢出的原因是当算术运算试图创建一个超出可以用给定位数表示的范围的数值时,大于最大值或小于可表示的最小值值。

  • 好吧,在你的例子中变量 i 没有被初始化。所以这里会发生的是分配给整数类型变量 i 的内存 space 将包含一些垃圾值。
  • 如果内存地址包含最大可能的整数值,即 -2^31(-2,147,483,648),则取反该值将导致整数溢出。

希望对您有所帮助。

您在堆栈中的 "i" 的值在 main 启动时未定义。在调用 main() 之前运行的启动代码可以保留任何内容。

除此之外 Kashif 所说,负整数可以比非负整数低一个值,因为负数不需要为零留出空间。符号位中的“1”,其余所有位为零,在符号反转时会导致溢出。

16 位:-0x8000 == ~0x8000 + 1 == 0x7FFF + 1 == 0x8000
// "-" 负值 == invert + 1 == inverted + 1 == final 相同

该值的可能性很小,但存在。它不会发生,除非堆栈恰好包含有问题的数字。