The following little program is very awkward using GCC version 4.2.1 (Apple Inc. build 5664) on a Mac.
#include <stdio.h>
int main(){
int x = 1 << 32;
int y = 32;
int z = 1 << y;
printf("x:%d, z: %d\n", x, z);
}
The result is x:0, z: 1.
Any idea why the values of x and z are different?
Thanks a lot.
Short answer: the Intel processor masks the shift count to 5 bits (maximum 31). In other words, the shift actually performed is 32 & 31, which is 0 (no change).
The same result appears using gcc on a Linux 32-bit PC.
I assembled a shorter version of this program because I was puzzled by why a left shift of 32 bits should result in a non-zero value at all:
..using the command
gcc -Wall -o a.s -S deleteme.c(comments are my own)Ok so what does this mean? It’s this instruction that puzzles me:
Clearly k is being shifted left by 32 bits.
You’ve got me – it’s using the
sallinstruction which is an arithmetic shift. I don’t know why rotating this by 32 results in the bit re-appearing in the initial position. My initial conjecture would be that the processor is optimised to perform this instruction in one clock cycle – which means that any shift by more than 31 would be regarded as a don’t care. But I’m curious to find the answer to this because I would expect that the rotate should result in all bits falling off the left end of the data type.I found a link to http://faydoc.tripod.com/cpu/sal.htm which explains that the shift count (in the CL register) is masked to 5 bits. This means that if you tried to shift by 32 bits the actual shift performed would be by zero bits (i.e. no change). There’s the answer!