C/C++无符号整数溢出

Det*_*ing 15 c c++

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

在页166中,有说:

涉及无符号操作数的计算永远不会溢出,因为无法由结果无符号整数类型表示的结果以模数减少为大于可由结果类型表示的最大值的数.

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

Pub*_*bby 26

它意味着价值"环绕".

UINT_MAX + 1 == 0
UINT_MAX + 2 == 1
UINT_MAX + 3 == 2
Run Code Online (Sandbox Code Playgroud)

.. 等等

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

  • @ 0x499602D2在大多数硬件上都可以,但编译器可以进行优化. (4认同)
  • 它就像老式汽车里程表一样。如果读数最多为 999,999 英里,那么再多一英里就会变回零。 (2认同)

Seb*_*ach 5

没有溢出?

“溢出”在这里的意思是“产生一个不适合操作数的值”。由于应用了算术模数,因此该值始终适合操作数,因此不会溢出。

换句话说,在溢出实际发生之前,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)
...
Run Code Online (Sandbox Code Playgroud)

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


Mat*_*son 5

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

 uint8_t a = 42;
Run Code Online (Sandbox Code Playgroud)

我们再加上 240:

 a += 240;
Run Code Online (Sandbox Code Playgroud)

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

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

  • 措辞:“实现定义的行为”,编译器应记录行为,以及“未定义的行为”,编译器可以做他们想做的事情。编辑:哦,而且,用 C++ 的说法,“明确定义”将是“明确定义”:) (3认同)
  • @phresnel,我明白,这是很久以前的事了,但是“无需解释”是“未指定的行为”,与“未定义”的行为不同,它会产生合理的结果,但可能仍然有所不同。 (3认同)