Strange behavior of bitwise NOT (~)

a = 8

~a = -9 (int)

~a >> 6 = -1 (int)

(unsigned char)-1 = 255

~a = 0xFFFFFFF7, so b = (~a) >> 6 results in b = 0xFF; In case of c we have c = (~a); resulting in c = 0xF7, therefore c>>6 will be 3. Henning Makholm explains integer promotion nicely above. This article is also useful.


All arithmetic and bitwise operators in C always widen their arguments to at least int if they were originally shorter integral types. That's just how the language is defined. The language specification calls this the "integral promotion".

(The underlying reason for this is to make it easier to implement C on architectures where the hardware does not support efficient operations on shorter quantities than a full machine word. Of course, it's also partly just because it has always worked that way and cannot be changed without breaking a lot of existing code that depends on this behavior).