caution2toxic caution2toxic - 1 month ago 6
C Question

C strange behaviour when bit-shifting

Why the following code, compiled with gcc, prints "ffffffff 0" instead of "0 0"? The bits are shifted to the right by 32 positions in both instructions. It doesn't make much sense, since x == 32, but still this strange result happens...

#include <stdio.h>

int main(void)
{
int x = 32;
printf("%x\n", 0xffffffff >> x);
printf("%x\n", 0xffffffff >> 32);
return 0;
}


Edit:
enter image description here

Edit2:
Yes, the compiler warned me. But this is not the point. I am using 0xffffffff as a mask that I bitshift with a variable. For example, when I bitshift with 8 I want 0xffffff (and it does that). When I bitshift with 31 I want 0x1 as a result (and it does that). And when I bitshift with 32 it gives me 0xffffffff (instead of 0, which is the beahaviour when I have 32 as a literal, not a variable). It is strange and for my purpose it is really unconvenient to make a special case for 32 since it should give 0 (and it does, but only when 32 is a literal)

Answer

Assuming int and unsigned int are 32 bit wide, the integer constant 0xffffffff is of type unsigned int.

Right shifting an integer with a value of greater or equal the width of the integer will result in undefined behavior1.

This happens in both cases in your example.

Update:

Undefined behavior means that anything can happen. Getting the value 0xffffffff instead of 0 fits this behavior.

You cannot shift by the width of the integer type, because it says so in the standard. You must make a check if the value is greater or equal the width of the type your working with.


1 (Quoted from: ISO/IEC 9899:201x 6.5.7 Bitwise shift operators 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.

Comments