When shifting an int by its size in bits, the results seems to vary depending on whether variables are involved or not. For example, the following program will produce the output 0 -1 and not the expected 0 0 int main() { int a = 24, b = 8; printf("%d\n%d", ~0 << 32, ~0 << (a + b)); } It seems that C << (a + b), where C is some constant integer and a and b are variables that add up to 32 (I have only compiled and run this program on 32 bit systems), will always get evaluated to C. Changing ~0 << 32 to ~0 << 32 + a - a does not change the behaviour, I'm guessing as the optimizer realizes that this is still a constant expression. Changing it to ~0 << 32 + a + a - 2*a , however, Does change the behaviour, as the optimizer isn't smart enough to realize that this too is a constant expression. Now, the output is, -1 -1 This suggests that the problem lies in how shifts are handled in non-constant expressions. Interestingly, the behaviour changes to the expected (correct?) one when compiling with optimizations (any of the -O's). gcc -v output: Using built-in specs. Configured with: FreeBSD/i386 system compiler Thread model: posix gcc version 3.4.2 [FreeBSD] 20040728 The system is FreeBSD 5.4. I'm using the gcc that came prebuilt with it. I had the following compilation warnings: In function `main': 3: warning: left shift count >= width of type Ulf