这本书大错特错。没有未定义的行为
signed char c = 256;
256
是类型的整数文字int
。为了用它初始化 a signed char
,它被转换为signed char
(§8.5 [dcl.init]/17.8;所有引用都指向 N4140)。此转换受 §4.7 [conv.integral] 的约束:
1 整数类型的纯右值可以转换为另一种整数类型的纯右值。无作用域枚举类型的纯右值可以转换为整数类型的纯右值。
2 如果目标类型是无符号的,则 [...]
3 如果目标类型是有符号的,如果它可以在目标类型(和位域宽度)中表示,则值不变;
否则,该值是实现定义的。
如果signed char
不能表示 256,则转换产生一个实现定义的 type 值,signed char
然后用于初始化c
。这里没有什么未定义的。
当人们说“签名溢出是 UB”时,他们通常指的是 §5 [expr]/p4 中的规则:
如果在计算表达式期间,结果未在数学上定义或不在其类型的可表示值范围内,则行为未定义。
This renders UB expressions like INT_MAX + 1
- the operands are both int
s, so the result's type is also int
, but the value is outside the range of representable values. This rule does not apply here, as the only expression is 256
, whose type is int
, and 256 is obviously in the range of representable values for int
.