3

Can someone explain me why right 32 bitwise shift of some 4 byte integer number may return not zero in C/C++ ? Why does it depend on -O option of the compiler?

For example this code gives 45 with -O0 and 0 with -O3 options in gcc 4.8.3:

unsigned int x = 45; // 4 bytes
x = x >> 32;
printf("%u\n", x);

Why it is like this?

Spikatrix
  • 20,225
  • 7
  • 37
  • 83

1 Answers1

21

Because it is undefined behavior: [expr.shift] says

The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

As for the specific undefined behavior, I imagine it is as follows:

  • With -O0, it compiled to actually perform a right shift in machine code, and on some machines (e.g. I believe x86 is such), shift functions only look at the low 5 bits of the shift amount when shifting a 32-bit word; shifting by 32 is the same as shifting by 0.
  • With -O3, the compiler computed the constant itself, and just put 0 into the program rather than having it do a calculation.

You can check the assembly output to see if my prediction is right.

  • I expected the second behavior, however in my code that depends on this behavior and was compiled with -O3 flag, I do have non-zero results with 32 shifts. Maybe it's because the compiler performs -O3 optimization not uniformly. So, at the end of the day you can't rely on this. It is undefined as you said. – Denis Yurin Jul 04 '15 at 07:07
  • PS: but I think it is not right, it should be defined: bits coming from the left side should be zeros. Period. – – Denis Yurin Jul 04 '15 at 07:28