Fragment Mismatch

Although the fragments below have a slight difference in the manipulation of the find variable, the result still seems the same. Why is that?

First snippet

#include<iostream> using namespace std; int main() { int number = 3,find; find = number << 31; find *= -1; cout << find; return 0; } 

Second fragment

  #include<iostream> using namespace std; int main() { int number = 3,find; find = number << 31; find *= 1; cout << find; return 0; } 

The output for both fragments:

 -2147483648 

(according to Ideone: 1 , 2 )

+4
source share
1 answer

In both of your examples, assuming 32bit int s, you invoke undefined behavior, as indicated in Why does a left shift operation cause undefined behavior when the left side operand has a negative value?

Why? Because number is a signed int , with 32 bits of memory. (3<<31) does not appear in this type.

Once you are in the area of ​​undefined behavior, the compiler can do what it likes.

(You cannot rely on any of the following because this is UB - it's just watching what your compiler does).

In this case, it looks like the compiler is doing a right shift, resulting in 0x80000000 representing a binary representation. This turns out to be a two-component representation of INT_MIN . Thus, the second fragment is not surprising.

Why does the first output the same thing? In two additions MIN_INT will be -2^31 . But the maximum value is 2^31-1 . MIN_INT * -1 will be 2^31 (if it were representable). And guess what idea would be? 0x80000000 . Get back to where you started!

+4
source

All Articles