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

Fit*_*rcy 11 c++ language-lawyer

我花了一些时间在这个网站上搜寻; 特别是这个问题:((a +(b&255))&255)是否与((a + b)&255)相同?

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

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

可能会导致不确定的行为因型促销ijint随后溢出于乘法!也许i,j甚至不需要这么大.

我的结论是,例如,在unsigned short16位且int为32位的系统上,行为可能是不确定的.

我在这里纠正吗?

krz*_*zaq 12

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

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

我正在使用N4140作为报价.

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

§4.5[conv.prom]/1

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

然后:

§5[expr]/4

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

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