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

C++ 两个无符号短路的乘法真的会导致未定义的行为吗?,c++,language-lawyer,C++,Language Lawyer,我花了一些时间拖网这个网站;特别是这个问题: 在这样做的过程中,我得出的结论是 int main() { unsigned short i = std::numeric_limits<unsigned short>::max(); unsigned short j = i; auto y = i * j; } intmain() { 无符号短i=std::numeric_limits::max(); 无符号短j=i; 自动y=i*j; } 由于将i和j类型

我花了一些时间拖网这个网站;特别是这个问题:

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

int main()
{
    unsigned short i = std::numeric_limits<unsigned short>::max();
    unsigned short j = i;
    auto y = i * j;
}
intmain()
{
无符号短i=std::numeric_limits::max();
无符号短j=i;
自动y=i*j;
}
由于将
i
j
类型提升为
int
,会导致未定义的行为,随后在乘法时溢出!也许
i
j
甚至不需要这么大

我的结论是,例如,在一个系统上,
unsigned short
是16位,
int
是32位,行为可以是未定义的。


我说的对吗?

是的,这是可能的,而且您的示例可能在大多数桌面架构上都没有定义

在本例中,假设
int
是32位2的补码类型,
无符号短
是16位

我使用N4140作为报价

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

§4.5[conv.prom]/1

除bool、char16\u t、char32\u t或 其整数转换秩(4.13)小于 如果int可以表示所有值,则int可以转换为int类型的prvalue 源类型的值

然后:

§5[expr]/4

如果在表达式求值期间,结果不是 数学定义的或不在可表示值范围内的 其类型、行为未定义


由于65535×65535(4294836225)的结果未在我们的32位<代码> INT/COD>中定义(值范围[-214783682147883647 ]),行为未定义。overflow@apple不这是不对的。很遗憾,你不能对一个评论投否决票。@Yakk@FitzwilliamBennet-Darcy你能解释一下为什么它没有定义吗?我认为

I
j
不适合
prvalue
作为@krzaqquote@appleapple他们将首先进行从左值到右值的转换。它在我的电脑上溢出,上面的例子是用VS 2013编译的。答案很好!我认为推广规则是C语言中最糟糕的事情之一(在语言设计方面),不幸的是它被C++采纳了。它们是无数细微缺陷的来源。幸运的是,编译器可以在某个时候发出警告。如果该值不能放入整数,表达式的类型不会被提升为无符号整数吗?@0x499602D2不,我引用了相关的paragraphs@vsoftco如果升级更改了值(这是唯一的问题),可以使用-Wconversion,如下所述: