8

我刚开始在学校学习 C,我正在努力掌握基本概念。

我们的作业有一个问题,

对于每个int x: x+1 > x

判断真假,真假推理,假反例。

我很困惑,因为我们被告知 int 类型是 32 位的,基本上这意味着整数是二进制格式。x+1 是在十进制值 1 上加 1 吗?

4

4 回答 4

25
x + 1 > x

1针对每个int值,除了 value INT_MAXwhereINT_MAX + 1是溢出,因此x + 1 > xexpression 是xvalue of 的未定义行为INT_MAX

这实际上意味着编译器有权优化表达式:

x + 1 > x

经过

1

作为INT_MAX + 1未定义的行为,编译器有权说对于这个特定的>表达式INT_MAX + 1> INT_MAX.

由于x + 1 > x表达式是 的未定义行为,因此假设它是 false ( )x == INT_MAX也是不安全的。x + 1 > x0

请注意,如果x声明为 anunsigned int而不是 an int,情况则完全不同。unsigned int操作数永远不会溢出(它们环绕):UINT_MAX + 1 == 0因此x + 1 > x适用0于所有其他x == UINT_MAX值。1x

现代编译器(如gcc)通常会借此机会优化此表达式并将其替换为1.

作为记录,已知服务器程序使用以下代码存在一些严重的安全问题:

 if (ptr + offset < ptr)

该代码旨在触发安全条件,但编译器会优化if语句(通过将表达式替换0为正确)。

于 2013-07-05T20:52:40.943 回答
4

注意 32 位数字范围[-2147483648, 2147483647]等于 [-2 31 , 2 31 -1 ]。

所以 for 表达式x+1 > x为真[-2147483648, 2147483646]

但不是2147483647因为添加到214748364732 位大小的数字会导致位溢出许多实现它使x + 1-2147483648真正的行为在 C 标准中是未定义的。

所以,

  • x + 1 > x仅 适用x[-2147483648, 2147483646]
  • x + 1 > x , for x = 2147483647 is Undefined value 可能是 True 或 False 取决于编译器。如果编译器计算 =-2147483648值将是 False。
于 2013-07-05T20:58:45.443 回答
2

我不想给你答案,所以我会回答一个应该让你走上正轨的问题。

可以存储在 32 位有符号整数中的最大可能值是什么x + 1时候?x(2,147,483,647)

于 2013-07-05T20:52:27.247 回答
-1

是的,x + 1 添加到十进制值 1。

这几乎在所有时间都是正确的。但是,如果您将 1 添加到 INT_MAX(即 2 15 - 1 或更大),您可能会翻转符号。想想0111111vs的十进制表示11111111。(显然不是 32 位,但想法成立。)

如果您对它翻转的原因感到困惑,请查看二进制补码。这是一个非常聪明的整数实现,使加法变得容易。

编辑:INT_MAX + 1是未定义的行为。不一定变成INT_MIN. 但既然x + 1不一定是> xwhen x == INT_MAX,那么答案显然是错误的!

于 2013-07-05T20:54:40.533 回答