c - 是否溢出intN_t定义明确



在C99中有一些(可选)类型,如int8_tint16_t等,它们保证具有精确指定的宽度并且没有填充位,并表示二进制补码(7.18.1.1)中的数字。在6.2.6.2中,有符号整数溢出被提及为脚注44)和45),即它可能导致在填充位中捕获值。

由于intN_t没有任何填充位,并且它们保证是两个的补充,这是否意味着它们的溢出不会产生任何未定义的行为?例如溢出乘法的结果是什么?加法呢?结果是否减少了无符号类型的模2^N

注不是规范性的。如果脚注指出溢出会导致在填充位中捕获值,那并没有真正错误,但我可以看到它有点误导。规范性文本只是说行为是未定义的。将陷印值放在填充位中是未定义行为的一个可能结果,但不是唯一的结果。

所以不,这并不意味着定义了溢出。涉及 intN_t/uintN_t 操作数的操作数可能会溢出,并且溢出可能会导致未定义的行为。

int8_t i = 127; ++i;这样的东西没有 UB。 int8_t受到整体促销的影响,因此添加就像您写了i = (int8_t) ((int) i + 1);一样进行。添加本身不会溢出,并且转换回int8_t会产生实现定义的结果。

uint16_t u = 65535; u *= u;这样的东西在当前的典型实现中具有UB,其中int具有32个符号/值位。 uint16_t也受到积分提升的影响,因此乘法就像您写了u = (uint16_t) ((int) u * (int) u);一样进行。乘法本身溢出,并且行为未定义。

int64_t i = 9223372036854775807; ++i;这样的东西在几乎所有的实现上都有UB。添加本身溢出。

不,它没有很好地定义,因为...它根本没有定义。标准中根本没有文本可以为有符号整数的溢出提供语义。

不要过分强调"未定义的行为"一词是神秘的,而是要直接理解它。没有行为的定义,因此标准没有指定应该发生的任何情况,并且任何可移植代码都不应依赖于此类功能。

相关内容

  • 没有找到相关文章

最新更新