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

标签 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 位的系统上,行为可以是 未定义

我在这里是正确的吗?

最佳答案

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

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

我使用 N4140 进行报价。

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

§ 4.5 [conv.prom] / 1

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type;

然后:

§ 5 [expr] / 4

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

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

关于c++ - 两个无符号短裤的乘法真的会导致未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40785566/

相关文章:

c++ - 如何强制用户在从菜单中选择之前输入一些数字?

c++ - 堆上的对象和引用

c++ - 对象生命周期结束和它何时不复存在之间有什么关系?

c++ - 如何使用 SDL C++ 在 win32 窗口中设置 GUI 按钮?

c++ - 为什么在我的代码中调用复制构造函数而不是移动构造函数?

c++ - 为什么编译器不能决定在没有引用运算符的情况下调用哪个函数?

c++ - 像 "Foo(12,3);"这样的未命名变量的强制构造仍然是声明符吗?

c++ - 如何优化C++程序运行MPI?

c++ - 不直接继承的基模板类成员的可见性

c++ - 为什么 std::array< T, 0 > 不为空?