C++11 §3.9.1/4, full quote:
” Unsigned integers, declared unsigned
, shall obey the laws of arithmetic modulo 2n where n is the number
of bits in the value representation of that particular size of integer.
Apart from the slightly misleading wording about “declared unsigned
” this might seem to apply that every arithmetic expression that involve only argument of some given unsigned type, will yield a result modulo 2n for that type.
However, there are no arithmetic expressions at all for unsigned types of lower conversion rank than int
: all arguments in an apparent such expression are converted up to (1)at least int
, or depending on the number ranges of the C++ implementation, up to unsigned int
.
As a result, a*b
where a
and b
are unsigned short
values, (2)can have formally Undefined Behavior. Because it's not an unsigned short
expression. It's (in practice) an int
expression.
也就是说,使用一个合理的编译器,不会在注意到正式 UB 的地方引入特殊大小写,并且在实践中使用 8 位字节和unsigned short
可以表示的最大值int
,以及常见的二进制补码有符号整数表示,结果转换回unsigned short
, 将as if它是范围内的模算术unsigned short
。这是因为在机器代码级别,二进制补码只是以 0 为中心范围的模算术。
(1) In practice one will usually be using an 8 bits-per-byte implementation where the maximum value of unsigned short
fits well within the int
range, so in practice we're talking about a conversion up to int
.
(2) E.g., for 16-bit unsigned short
and 32-bit int
, (216−1)2 = 232−2×216+1 > 231−1, where the last value is the maximum positive int
value.