c++ - 为什么定义了无符号整数溢出行为但没有定义有符号整数溢出?

标签 c++ c undefined-behavior integer-overflow

无符号整数溢出在 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/

相关文章:

c++ - Qt:识别 QTreeView 的项目

c++ - 如何在 OS X 上的 Qt 应用程序中设置应用程序图标,足以分发?

c - 使用 CMake 查找介子依赖性

c - 在 C 中将 Char* 复制到 Char* 时遇到问题

java - Android调试器隐藏局部变量

c - 将 char 指针强制转换为 int 指针是未定义的行为吗?

c++ - 我怎样才能让 GCC/Clang 警告使用未初始化的成员?

c - Hook - 热修补

c++ - 指向释放变量的指针更改地址

c++ - strcpy() 导致段错误?