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
The bitwise NOT operator in C++ is the tilde character ~ . Unlike & and |, the bitwise NOT operator is applied to a single operand to its right. Bitwise NOT changes each bit to its opposite: 0 becomes 1, and 1 becomes 0.
Bitwise NOT (~) Each bit in the operand is inverted in the result. The 32-bit signed integer operand is inverted according to two's complement. That is, the presence of the most significant bit is used to express negative integers. Bitwise NOTing any number x yields -(x + 1) .
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).
~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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With