1 << 31
causes undefined behaviour, if your system has 32-bit ints. The literal 1
is a signed int.
You need to do an unsigned shift instead of a signed shift:
x = 1UL << 31;
I added L
so that the code is still correct even on a 16-bit system, and it doesn't hurt to do so.
Informally, shifting a 1
into the sign bit is undefined. The formal text can be found in section 6.5.7/4 of the C11 standard:
The result of E1 << E2
is E1
left-shifted E2
bit positions; vacated bits are filled with zeros. [...] If E1
has a signed type and nonnegative value, and E1
× 2
E2
is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
Your other question, "why can't I use 1 << 32
" is covered by that same quote. What about 1UL << 32
? If your system has 32-bit unsigned long
then this would also be undefined according to 6.5.7/3:
[...] If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined
But it would work if your system had 64-bit unsigned long
. To avoid having your code break when compiled on a different system (this goal is known as code portability) you could write (uint64_t)1 << 32
(or 1ULL << 32
) which is guaranteed to work.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…