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.