How do I explain the following behavior?
#include<iostream>
using namespace std;
int main(){
unsigned char a = 8;
cerr << "a: " << (int)a << '\n';
unsigned char b = (~a) >> 6;
cerr << "b: " << (int)b << '\n';
unsigned char c = (~a);
c = c >> 6;
cerr << "c: " << (int)c << '\n';
return 0;
}
Output:
a: 8
b: 255
c: 3
After further testing it seems that (~a) becomes an int rather than unsigned char. This is why the 1‘s get shifted in.
What’s going on?
EDIT: My compiler is just standard gcc 4.1.2
All arithmetic and bitwise operators in C always widen their arguments to at least
intif 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).