[expr.shift]/1 The value of E1 << E2
is E1
left-shifted E2
bit positions; vacated bits are zero-filled. ... if E1
has a signed type and non-negative value, and E1 × 2^E2
is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.
Emphasis mine. Your program exhibits undefined behavior.
Edit: Upon closer consideration, I no longer think it's undefined behavior. 2147483647*2
does fit into unsigned int
, "the corresponding unsigned type" of int
. Its conversion to int
is not undefined, but merely implementation-defined. It's entirely reasonable for an implementation using two's complement to define this conversion so that 2147483647*2 == -2
, just reinterpreting the bit pattern, as other answers explained.