C ++中有符号整数溢出仍然是未定义的行为?

正如我们所知,有符号整数溢出是未定义的行为 。 但在C ++ 11 cstdint文档中有一些有趣的cstdint

有符号整数types,其宽度分别为8,16,32和64位,没有填充位, 2的补码用于负值 (只有在实现直接支持该types时才提供)

请参阅链接

这里是我的问题:因为标准明确指出,对于int8_tint16_tint32_tint64_t负数是2的补码,仍然是这些types的溢出未定义的行为?

编辑我检查了C ++ 11和C11标准,这里是我发现:

C ++ 11,§18.4.1:

标题定义了与C标准中的7.20相同的所有函数,types和macros。

C11,§7.20.1.1:

typedef名称intN_t指定宽度为N,无填充位和二进制补码表示的有符号整数types。 因此, int8_t表示宽度恰好为8位的带符号整数types。

仍然是这些types溢出一个未定义的行为?

是。 根据C ++ 11标准第5/4段(关于一般expression方式):

如果在expression式评估过程中,结果不是math定义的,或者不在其types的可表示值范围内, 则行为是未定义的 。 […]

对这些有符号types使用二进制补码表示的事实并不意味着在对这些types的expression式进行求值时使用算术模2 ^ n。

关于无符号算术,另一方面,标准明确规定(第3.9.1 / 4段):

无符号整数, unsigned符号整数, 应遵循算术模2 ^ n的定律,其中n是特定大小整数的值表示中的位数

这意味着无符号算术运算的结果总是“ math定义的 ”,并且结果总是在可表示的范围内; 因此,5/4不适用。 脚注46解释了这一点:

46)这意味着无符号算术不会溢出,因为无法用结果无符号整数types表示的结果被减less的模数大于可由无符号整数types表示的最大值的数。

仅仅因为一个types被定义为使用二进制补码表示,所以不会在该types的算术溢出被定义。

有符号运算溢出的未定义行为用于启用优化; 例如,编译器可以假设如果a > b那么a + 1 > b也是; 这不适用于无符号math运算,因为可能a + 1可能回绕到0 ,所以需要进行第二次检查。 另外,有些平台可能在算术溢出时产生一个陷阱信号(见http://www.gnu.org/software/libc/manual/html_node/Program-Error-Signals.html )。 该标准继续允许这种情况发生。

我敢打赌。

从标准文件(第4和5页):

1.3.24未定义的行为

本国际标准没有规定的行为

[注:当本标准忽略任何明确的行为定义或程序使用错误的结构或错误数据时,可能会出现未定义的行为。 允许的未定义的行为范围从完全忽略情况,以不可预知的结果,在翻译或程序执行期间以文档化的方式performance环境特征(不论是否发布诊断消息),终止翻译或执行(发行的诊断消息)。 许多错误的程序结构不会产生未定义的行为; 他们被要求被诊断.–尾注]