【发布时间】:2014-04-01 13:00:41
【问题描述】:
解决了!
相关段落可以在 C90 ISO 9899:1990 6.1.2.5 Types 中找到:
"[..] 涉及无符号操作数的计算永远不会溢出,因为 [...]"
因此 9899:1990 6.3 不能应用,因此不能是未定义的行为。
- C90:见下面的full answer。
- C99:请参阅 answer 以获取 "Is unsigned integer subtraction defined behavior?"
感谢 Keith Thompson 帮助我阅读。 :-)
[2014-03-14] 显然,无符号短整数可能会溢出,从而导致未定义的行为,具体取决于目标环境。如果短无符号整数在算术上提升为 int,则会发生这种情况。详情见updated answer 和 supercat 的 cmets。感谢双方。 :-)
原问题:
首先,对不起我的英语不好……我尽力了。这是我的第一个问题,我认为这是一个非常愚蠢的问题。
由于一些可悲的原因,我的公司仍然坚持使用 ANSI C90 (ANSI/ISO 9899:1990),因此我手头有该标准的旧副本,但仍然缺少更正和修正。
我有一个非常简单的问题,并且在我学习期间非常清楚答案 - 直到我尝试按照标准阅读它。
如果我在加法时出现无符号整数溢出会发生什么。请看这段代码:
uint32_t a,b,c;
b = UINT_MAX;
c = UINT_MAX;
a = b + c; /* Overflow here - undefined behavior? */
我所知道的就是,无符号整数会在需要时回绕,一切都很好,但并非总是如此。
现在我正在寻找标准中的相应部分。
当然有 ISO 9899:1990 6.2.1.2 描述了无符号整数的环绕,无论何时转换。还有一点 6.2.1.5 的“常用算术转换”,它描述了类型如何变得更宽,主要是表达式的两个操作数具有相同的类型。
现在有 6.3 个“表达”与我有关。我引用:
“[...] 如果在计算表达式期间发生异常(即,如果 结果未在数学上定义或不在可代表值的范围内 对于它的类型)行为是未定义的。 [...]”
关于加法运算符的第 6.3.6 章说:
- 对操作数进行通常的算术转换,这并不适用,因为一切都是 uint32_t。
- 结果是两者之和,显然不适合 uint32_t。
- 很好
没有说,结果值被转换为结果类型 - 所以 6.2.1.2 不适用。但随后值明显溢出,6.3 步入其中。
据我所知 - 根据 ISO 9899:1990,这是未定义的行为。我错过了什么?勘误中有什么东西吗?我是否遗漏了标准中的一行或一个单词?
我现在真的很困惑。 :-)
关于, 标记
问题更新
[2014-03-03]已解决
[2014-03-03] 因此,多亏了 Acme,我现在有了一个明确而完整的答案对于 ANSI C99(请参阅答案: "Is unsigned integer subtraction defined behavior":这是按预期明确定义的行为。尽管我也希望 适用于 ANSI C90,但鉴于上面的文本段落,我仍然无法从 ISO 9899:1990 的文本中读出它。所以我认为我的问题目前仍未得到解答。
编辑:只是错别字| Edit2:添加 C90 和标准标签 | Edit3:添加问题更新 | Edit4:添加已解决部分 | Edit5:添加答案链接:-) | Edit6:更新短无符号整数溢出 | Edit7:一些错别字
【问题讨论】:
-
我相信lysator.liu.se/c 有(在最终版本旁边)成为 ANSI C/C90 的草案。也许comp.lang.c FAQ 有助于查找副本。
-
感谢 vonbrand - 我有一份标准的副本,但阅读能力很差。
-
最后我是对的。这是一个愚蠢的问题! :-)
标签: c standards undefined-behavior unsigned-integer c89