【问题标题】:C/C++ unsigned integer overflowC/C++ 无符号整数溢出
【发布时间】:2013-04-10 00:31:14
【问题描述】:

我正在阅读有关整数安全性的文章。 这是链接: http://ptgmedia.pearsoncmg.com/images/0321335724/samplechapter/seacord_ch05.pdf

第166页说:

涉及无符号操作数的计算永远不会溢出,因为 结果不能用得到的无符号整数表示 类型被模减为比 结果类型可以表示的最大值。

这是什么意思?感谢您的回复。

【问题讨论】:

  • 那是……误导。它溢出了。但它以一种明确的方式这样做,即以他们解释的方式包装。
  • @harold:这是语义问题。例如,C++ 标准的作者说它不会溢出,因为模运算将结果保持在范围内;他们只使用该术语来描述有符号溢出,这是一个给出未定义行为的错误。
  • @harold 它来自 n1570 标准§6.2.5/9

标签: c++ c


【解决方案1】:

表示值“环绕”。

UINT_MAX + 1 == 0
UINT_MAX + 2 == 1
UINT_MAX + 3 == 2

..等等

正如链接所说,这就像模运算符:http://en.wikipedia.org/wiki/Modulo_operation

【讨论】:

  • 我知道签名溢出是未定义的行为,但它不会太绕吗?
  • @0x499602D2 在大多数硬件上都可以,尽管编译器可以进行优化而不会。
  • 它就像一个老式汽车里程表。如果它最多只能读取 999,999 英里,那么再多行驶一英里就会将其归零。
  • C++ 标准中的定义在哪里?
【解决方案2】:

没有溢出?

“溢出”在这里的意思是“产生一个不适合操作数的值”。因为应用了算术模,所以值总是适合操作数,因此不会溢出。

换句话说,在溢出实际发生之前,C++ 已经截断了值。

取模?

取一个值取模其他值意味着应用除法,然后取余数。

例如:

0 % 3 = 0  (0 / 3 = 0, remainder 0)
1 % 3 = 1  (1 / 3 = 0, remainder 1) 
2 % 3 = 2  (2 / 3 = 0, remainder 2)
3 % 3 = 0  (3 / 3 = 1, remainder 0)
4 % 3 = 1  (4 / 3 = 1, remainder 1)
5 % 3 = 2  (5 / 3 = 1, remainder 2)
6 % 3 = 0  (6 / 3 = 2, remainder 0)
...

这个模应用于无符号计算的结果,除数是该类型可以容纳的最大值。例如,如果最大值为 2^16=32768,则 32760 + 9 = (32760 + 9) % (32768+1) = 0。

【讨论】:

    【解决方案3】:

    这意味着您不能更改unsigned 计算的符号,但它仍然会产生意想不到的结果。假设我们有一个 8 位无符号值:

     uint8_t a = 42;
    

    我们再加上 240:

     a += 240;
    

    它不适合,所以你得到 26。

    在 C 和 C++ 中明确定义了无符号数学,其中有符号数学在技术上要么是未定义的,要么是依赖于实现的,或者是其他一些“你不会期望可能发生的事情”的措辞(我不知道确切的措辞,但结论是“你不应该依赖有符号整数值的溢出行为”)

    【讨论】:

    • 措辞:“实现定义的行为”,当编译器应记录行为时,以及“未定义的行为”,编译器可以做他们想做的事。编辑:哦,“明确定义”在 C++ 用语中将是“明确定义”:)
    • 我认为(至少)有第三个类似于“实施细节”,但我的意思是我不知道“不确定这里发生了什么”的哪个级别有符号整数数学最终会出现 - 它是否只允许“奇怪的结果”或“任何事情都可能发生”(例如,如果处理器有一个在整数溢出时触发的溢出陷阱会发生什么?)
    • “实现细节”在 C++ 用语中是“定义的实现”。在不审查标准的情况下,我认为溢出的有符号值会导致未定义的行为。
    • 我的印象是有一个微妙的区别:“实现定义”意味着编译器生产者必须告诉你他们做了什么。 “实现细节”的意思是“由编译器生产者决定,不需要解释它是”。无论哪种方式,“不要溢出有符号整数”就是结论。
    • @phresnel,我明白,这是很久以前的事了,但是“无需解释”是“未指定的行为”,与“未定义”不同,它会产生合理的结果,但可能仍会有所不同。跨度>
    猜你喜欢
    • 2014-12-09
    • 2021-03-15
    • 2023-03-15
    • 1970-01-01
    • 2011-05-13
    • 2012-02-29
    • 2018-09-07
    • 2011-04-23
    • 1970-01-01
    相关资源
    最近更新 更多