我刚开始在学校学习C,我正试图掌握基本概念。
我们的作业有一个问题,
每个int x: x+1 > x
的
确定是真还是假,如果为真,则给出推理,如果为假,则给出反例。
我很困惑,因为我们被告知类型int是32位,基本上这意味着整数是二进制格式。 x + 1是否将1添加到1的十进制值
答案 0 :(得分:25)
x + 1 > x
每个1
值的{{1>}都是int
,但值INT_MAX
除外,其中INT_MAX + 1
是溢出,因此x + 1 > x
表达式是x
的未定义行为INT_MAX
的价值。
这实际上意味着编译器有权优化表达式:
x + 1 > x
通过
1
由于INT_MAX + 1
是未定义的行为,编译器有权说这个特定的>
表达式INT_MAX + 1
是> INT_MAX
。
由于x + 1 > x
表达式是x == INT_MAX
的未定义行为,因此假设x + 1 > x
可能为false(0
)也是不安全的。
请注意,如果x
被声明为unsigned int
而不是int
,则情况完全不同。 unsigned int
操作数永远不会溢出(它们会回绕):UINT_MAX + 1 == 0
因此x + 1 > x
0
为x == UINT_MAX
而1
为x
gcc
1}}值。
现代编译器(如1
)通常会借此机会优化此表达式并将其替换为 if (ptr + offset < ptr)
。
对于记录,使用以下代码的已知服务器程序存在一些严重的安全问题:
if
代码旨在触发安全条件,但编译器会优化0
语句(通过将表达式替换为{{1}}),并允许攻击者在服务器程序中获得权限提升(如果我没记错的话,通过打开可利用的缓冲区溢出的可能性)。
答案 1 :(得分:4)
注意,32位数字范围是[-2147483648, 2147483647]
,等于[-2 31 ,2 31 -1]。
因此,对于x+1 > x
[-2147483648, 2147483646]
是正确的
但不适用于2147483647
,因为在32位大小的数字中添加2147483647
会导致bit overflow许多实现x + 1
到-2147483648
但真正的行为是
未在C标准中定义。
所以,
x + 1 > x
仅对x
{/ 1}}中的[-2147483648, 2147483646]
为真
x + 1 > x
,对于x = 2147483647
,未定义的值可能为True或False取决于编译器。如果编译器计算= -2147483648
,则值为False。 答案 2 :(得分:2)
我不想把答案递给你,所以我会回答一个问题,让你走上正确的道路。
当x + 1
是可以存储在32位有符号整数中的最大可能值时,x
是什么? (2,147,483,647)
答案 3 :(得分:-1)
是,x + 1会将十进制值加1。
几乎所有时间都是如此。但是如果你将1加到INT_MAX(2 15 - 1或更大),你可以翻转符号。考虑0111111
与11111111
的十进制表示。 (显然不是32位,但这些想法仍然存在。)
如果你对它翻转的原因感到困惑,请查看两个补码。这是一个非常聪明的整数实现,使得添加变得容易。
编辑:INT_MAX + 1
是未定义的行为。不一定会成为INT_MIN
。但由于x + 1
在> x
时不一定是x == INT_MAX
,所以答案显然是错误的!