片段中的差异

Discrepancy in Snippet

本文关键字:片段      更新时间:2023-10-16

虽然下面的两个代码片段在find变量的操作上略有不同,但输出似乎是相同的。为什么如此?

第一个代码段

    #include<iostream>
    using namespace std;
    int main()
    {
    int number = 3,find;
    find = number << 31;
    find *= -1;
    cout << find;
    return 0;
    } 
<<p> 第二片段/strong>
   #include<iostream>
   using namespace std;
   int main()
   {
   int number = 3,find;
   find = number << 31;
   find *= 1;
   cout << find;
   return 0;
   } 

两个片段的输出:

-2147483648

(根据Ideone: 1,2)

在您的两个样本中,假设32位int s,您正在调用未定义行为,正如在左侧操作数具有负值时为什么左移位操作调用未定义行为中所指出的那样?

为什么?因为number是带符号的int,具有32位存储空间。(3<<31)在该类型中不可表示。

一旦进入未定义行为区域,编译器就可以为所欲为。

(您不能依赖以下任何内容,因为它是UB -这只是对编译器似乎正在做的事情的观察)。

在这种情况下,看起来编译器正在做正确的移动,导致0x80000000作为二进制表示。这恰好是INT_MIN的两个补表示。所以第二个代码片段并不奇怪。

为什么第一个输出相同的东西?在2的补码中,MIN_INT将是-2^31。但最大值是2^31-1MIN_INT * -1将是2^31(如果它是可表示的)。猜猜它的表示是什么?0x80000000。回到你开始的地方!