C99 标准在哪里说有符号整数溢出是未定义的行为?

Posted

技术标签:

【中文标题】C99 标准在哪里说有符号整数溢出是未定义的行为?【英文标题】:Where in the C99 standard does it say that signed integer overflow is undefined behavior? 【发布时间】:2016-03-31 19:50:26 【问题描述】:

C99 标准中的什么地方说有符号整数溢出是未定义的行为?

我在第 6.2.5 节中看到关于无符号整数溢出定义明确的评论(参见 Why is unsigned integer overflow defined behavior but signed integer overflow isn't?):

涉及无符号操作数的计算永远不会溢出, 因为不能用生成的无符号整数类型表示的结果是 以比最大值大一的数字为模减少,可以是 由结果类型表示。

但我在附录 J 中查看未定义的行为,我只在列表中看到这些类似的项目:

具有带符号提升类型的表达式左移,并且 表达式是否定的,否则移位的结果将无法在 提升类型

整数算术或转换函数的结果值不能 代表

(注意这里指的是“整数算术函数”,而不是整数算术本身

【问题讨论】:

C99 标准草案 n1256 6.5 表达式 5 如果在计算表达式期间出现异常情况(即,如果结果未在数学上定义或不在其可表示值的范围内) type),行为未定义。 @EOF:为什么不将其发布为答案? @NateEldredge:有一个引用 C11 草案标准的答案,据我所知,在这方面是相同的。 附录 J 是非规范性的,它只是一个总结 啊哈这个问题很相似:***.com/questions/3679047/… 【参考方案1】:

我没有 C99 的副本,但在 C11 标准中,此文本出现在第 6.5 节第 5 段中:

如果在计算表达式期间出现异常情况(即,如果结果未在数学上定义或不在其类型的可表示值范围内),则行为未定义。

这似乎是任何溢出的包罗万象;然后关于无符号整数的文本成为 6.5 ¶ 5 以上的特例。

【讨论】:

啊——我不知何故错过了这个。谢谢!似乎应该更强烈地说明对无符号溢出的评论;听起来标准的其他部分暗示了这一点(“哦,这是真的”),但我没有看到标准中其他地方引用的模行为。 是的;有点奇怪,它没有出现在附录 J 中,作为“结果值”规则的例外。很高兴我能帮上忙! @JasonS:你可以看看 C11 草案标准 n1570,6.2.6.2 整数类型 1 对于 unsigned char 以外的无符号整数类型,对象表示的位应分为两组:值位和填充位(不需要任何后者)。如果有 N 个值位,每个位应表示 1 和 2 N -1 之间的 2 的不同幂,以便该类型的对象应能够使用纯二进制表示表示从 0 到 2 N - 1 的值;这应称为值表示。未指定任何填充位的值。 天哪,这太具体了,我可以阅读它,而且它都非常有道理,我不知道为什么它很重要。 值得注意的是,许多实现预定义了宏,这些宏承诺浮点数学将根据附件进行,该附件定义了许多越界条件下的行为。此外,过去,整数存储和计算的二进制补码规范被认为是所有整数运算符和操作数组合的完整行为定义,除了在没有任何记录异常的情况下过大的移位或被零除。许多编译器会在启用某些优化后,在循环中执行某些线性变换,例如...

以上是关于C99 标准在哪里说有符号整数溢出是未定义的行为?的主要内容,如果未能解决你的问题,请参考以下文章

C:标准和编译器中的整数溢出

将负双精度转换为无符号整数的行为是不是在 C 标准中定义? ARM 与 x86 上的不同行为

C99 标准是不是保证 unsigned int 的二进制表示?

我看不懂C99中的一些句子

否定INT_MIN未定义的行为?

删除 null void* 指针是未定义的行为吗?