【发布时间】:2016-02-17 09:08:22
【问题描述】:
我在问自己,在某些情况下,是否将排名低于int 的所有类型(除了一些例外)提升到int 以执行算术运算可能会导致 UB。
例如:
unsigned short a = 0xFFFF;
unsigned short b = a*a;
由于 unsigned short 被提升为 int 以进行算术运算,这将导致:
unsigned short a = 0xFFFF;
unsigned short b = (int)a*(int)a;
由于(int)0xFFFF*(int)0xFFFF 导致溢出,而有符号类型的溢出是UB:在x*y > INT_MAX 的情况下,两个无符号短裤x,y 相乘会导致未定义的行为
更新:
这个问题专门针对int是32位,short是16位的情况。
【问题讨论】:
-
是的。结果是不使用转换等级低于
int的无符号类型进行算术运算。一个更简单的规则是不要对数字使用无符号类型,而是将它们用于位摆弄。 -
是的,这是有符号整数溢出导致 UB。一个令人讨厌的历史缺陷,它可以伪装起来,因为
uint16_t通常被实现为unsigned short的typedef。从理论上讲,uint32_t甚至会出现同样的问题,因为没有什么能阻止编译器使short在具有 64 位int的系统上成为 32 位。 -
@M.M:其实
short并没有什么特别之处。在算术运算发生之前,任何小于int的无符号类型都将被提升为int。如果int是 64 位,则尤其适用于uint32_t。 -
我认为你可以(理论上)通过乘以
size_ts 来产生相同的 UB,因为我没有在标准中找到它必须至少与 int 一样大的约束。 twitter.com/fugueish/status/637715389519015941
标签: c++ c++11 types casting integer-promotion