> 8); return 0; } I will compil...">

C hexadecimal constant type

I wrote the following c code:

#include <stdio.h> int main () { printf("%d\n", -1 >> 8); return 0; } 

I will compile this code with gcc 4.6.3 on my x86_64 using the -m32 flag. I get a -1 printout, as you would expect, the shift occurs arithmetically using two additional representations leading to -1.

Now, if I write instead

 printf("%d\n", 0xFFFFFFFF >> 8); 

I get 16777215. I would expect this constant to be interpreted as int (signed), and then the shift would be arithmetic, which would result in a -1 repetition. I looked at the latest C standard and I cannot understand why this is so. Any ideas?

+7
source share
2 answers

According to standard C99 (6.4.4.1), hexadecimal constants will be the first type in this list that can represent them:

 int unsigned int long int unsigned long int long long int unsigned long long int 

The hexadecimal literal 0xFFFFFFFF not suitable for int (which may contain values -0x80000000 to 0x7FFFFFFF ), but is suitable for unsigned int , so its type will be unsigned. An unsigned right shift of 0xFFFFFFFF by 8 gives 16777215 .

+10
source

Non-corrected integral literals have a different type depending on whether they are decimal or not (6.4.4.1/5 in C11, table 6 in C ++ 11):

  • decimal literals i.e. [1-9][0-9]* , always subscribe.

  • Hexadecimal and octal literals are either signed or unsigned. If the value is significant for the signed type, but small enough to correspond to an unsigned type of the same width, it will be unsigned. (This is what happens with your hexadecimal constant.)

On the right, the offset of negative integers is determined by the implementation, and you get a subscription extension. The right shift of an unsigned value is a simple division by two.

+10
source

All Articles