为什么C++没有将INT_MIN定义为(1<<31)?

4

我理解 C++ 之所以将 INT_MIN 定义为 (-2147483647 - 1) 的原因,但他们为什么不直接使用 1<<31 呢?那样可以避免溢出,并且易于理解。


就我个人而言,我发现将其定义为“-2147483648”会失败同样令人惊讶。我的意思是,这确实是确切的值,但编译器会抱怨它超出了范围。说实话,这很愚蠢。 - Matthieu M.
@MatthieuM。怎么可能在范围内?毕竟它是-(2147483648),而2147483648肯定大于32位平台上的INT_MAX - MSalters
@MSalters:也许这个“-”应该是数字字面量的一部分? - Matthieu M.
@MatthieuM。这是否也适用于-123?即空格是否是标记的一部分?这样的更改很少像看起来那么简单。您必须证明没有合理的程序会受到影响。 - MSalters
@MSalters:哦,我知道现在改变它可能是不可能的(当然,空格会打破一个标记,毕竟1 2 3不是123);我只是批评最初的决定。 - Matthieu M.
2个回答

7
它如何防止溢出,如果通过将正数左移来尝试获得负数呢?;)
请记住,有符号整数溢出是未定义行为。根据C++11标准第5.8/2段:
E1 << E2的值是E1向左移动E2个位位置;空出来的位都填充为零。 ……否则,如果E1具有带符号类型和非负值,并且E1×2^E2可以在结果类型的相应无符号类型中表示,则该值转换为结果类型后即为结果值;否则,行为未定义。
此外,根据第5/4段:
如果在表达式的求值过程中,结果在数学上没有定义或不在其类型的可表示值范围内,则行为是未定义的。 [...]

如果 E1 具有带符号类型 且为非负值... - cHao
@cHao:那是给Guillaume的吗? - Andy Prowl
@AndyProwl:是的,显然。 :) - cHao
由于INT_MIN是由实现定义的,因此“未定义行为”是完全可以接受的。几乎每个offset_of的实现都依赖于它,以及可变参数。 - MSalters
注意:在C++14中,这个问题被更改为实现定义。在评论中,Howard Hinnant解释说,这个更改是因为他厌倦了不得不写“-2147483647 - 1”。 - M.M
显示剩余6条评论

4

因为 1 << 31 调用了未定义行为(假设是32位的int)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接