I got some C code that confuses me:
int a = 1;
int b = 32;
printf("%d\n %d\n", a<<b, 1<<32);
The output is
1
0
The code was run on Ubuntu 16.04 (Xenial Xerus), and I compiled it using gcc -m32 a.c
with GCC version 5.4.0.
I've read some posts that have explained why a<<b
outputs 1, but I don't understand why 1<<32
results to 0. I mean, what is the difference between a<<b
and 1<<32
?
Shifting a 32-bit int
left by 32 is undefined behavior, so any value could be produced as the result. Your C compiler should warn you about it in case of 1<<32
expression.
The reason the two outputs that you see are different is that they are produced by different code paths:
a << b
uses variables, so it is computed at runtime by the compiled code1<<32
is a constant expression, so it is computed at compile time by the compiler itselfIt looks like the compiled code performs the shift by modulo 32, so shift by 32 is the same as a shift by zero. The compiler itself, however, shifts by 32, dropping the one bit off the end. The compiler is free to do this, because this behavior is undefined. Hence, the standard does not demand any particular behavior, or even a consistent behavior among parts of the same program.
a<<b
and 1<<32
are undefined behaviour, because your right operand is equal to the number of bits.
C11 §6.5.7 Bitwise shift operators
Paragraph 3:
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.The result is undefined if the right operand is negative, or greater than or equal to the number of bits in the left expression’s type.
Paragraph 4:
The result of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are filled with zeros. IfE1
has an unsigned type, the value of the result isE1 × 2E2
, reduced modulo one more than the maximum value representable in the result type. IfE1
has a signed type and nonnegative value, andE1 × 2E2
is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
So, if the number is shifted more than the size of integer, the behaviour is undefined.
GCC generated warning:
warning: left shift count >= width of type [-Wshift-count-overflow]
printf("%d\n%d",a<<b,1<<32);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With