无符号整数溢出在 C 和 C++ 标准中都有很好的定义。例如,C99 standard (§6.2.5/9
) 状态
A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
但是,两个标准都规定有符号整数溢出是未定义的行为。同样,来自 C99 标准 (§3.4.3/1
)
An example of undefined behavior is the behavior on integer overflow
这种差异是否有历史原因或(甚至更好!)技术原因?
最佳答案
历史原因是大多数 C 实现(编译器)只是使用最容易通过它使用的整数表示来实现的溢出行为。 C 实现通常使用 CPU 使用的相同表示形式 - 因此溢出行为遵循 CPU 使用的整数表示形式。
在实践中,只有符号值的表示可能会根据实现而有所不同:一个补码、二进制补码、符号大小。对于无符号类型,标准没有理由允许变化,因为只有一种明显的二进制表示(标准只允许二进制表示)。
相关引述:
C99 6.2.6.1:3:
Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.
C99 6.2.6.2:2:
If the sign bit is one, the value shall be modified in one of the following ways:
— the corresponding value with sign bit 0 is negated (sign and magnitude);
— the sign bit has the value −(2N) (two’s complement);
— the sign bit has the value −(2N − 1) (one’s complement).
现在,所有处理器都使用二进制补码表示,但有符号算术溢出仍未定义,编译器制造商希望它保持未定义,因为他们使用这种未定义来帮助优化。例如,参见 blog post通过 Ian Lance Taylor 或此 complaint作者:Agner Fog,以及他的错误报告的答案。
关于c++ - 为什么定义了无符号整数溢出行为但没有定义有符号整数溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18195715/