开发者

Strange behavior of bitwise NOT (~)

How do I explain the following behavior?

#include<iostream>

using namespace std;

int main(){

       unsigned char a = 8;

       cerr <&l开发者_如何学Pythont; "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 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.


a = 8

~a = -9 (int)

~a >> 6 = -1 (int)

(unsigned char)-1 = 255


because this line...

unsigned char b = (~a) >> 6;

compiler build the temporary var is signed char (~a) and after the shift right and LSB byte b is 0xff

but this lines...

   unsigned char c = (~a);
   c = c >> 6;

compiler not needed to build the temporary var and (~a) value is 0x7f, and after the shift right c is 0x03

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜