两个无符号短路的乘法是否真的会导致未定义的行为?

时间:2016-11-24 11:45:08

标签: c++ language-lawyer

我花了一些时间在这个网站上搜寻;特别是这个问题:Is ((a + (b & 255)) & 255) the same as ((a + b) & 255)?

在这样做的过程中,我得出的结论是

int main()
{
    unsigned short i = std::numeric_limits<unsigned short>::max();
    unsigned short j = i;
    auto y = i * j;
}

可能导致未定义的行为,因为ijint的类型提升会随后在乘法时溢出!可能ij甚至不需要这么大。

我的结论是,例如,在unsigned short为16位且int为32位的系统上,行为可能未定义。< /强>

我在这里纠正吗?

1 个答案:

答案 0 :(得分:12)

是的,这是可能的,并且您的示例可能在大多数桌面架构上都未定义。

为了这个例子,我们假设int是32位2的补码类型而unsigned short是16位。

我正在使用N4140作为报价。

在乘法之前,两个值都会提升为int

  

§4.5[conv.prom] / 1

     

除bool,char16_t,char32_t或之外的整数类型的prvalue   wchar_t,其整数转换等级(4.13)小于等级   如果int可以表示all,则int可以转换为int类型的prvalue   源类型的值;

然后:

  

§5[expr] / 4

     

如果在评估表达式期间,结果不是   在数学上定义或不在可表示值的范围内   它的类型,行为是未定义的。

由于65535 * 65535(4294836225)的结果未在我们的32位int中定义(值范围为[-2147483648,2147483647]),因此行为未定义。