views:

613

answers:

4

Could someone explain to me why the mask is not shifted to the right at all? You can use anything in place of that 1 and the result will be the same.

unsigned mask = ~0 >> 1;
printf("%u\n", mask);
+11  A: 

Sign extension

What's happening is ~0 is an int with all bits set (-1). Now you right shift by 1; since it's -1, sign extension keeps the highest bit set so it remained signed (this is not what you were expecting). Then it's converted to unsigned like you expect.

acidzombie24
+2  A: 

~0 is a string of ones. The >> operator shifts them, and in a signed value, it shifts ones into the higher order bits. So you can shift all you want, the result won't change.

Rob Lachlan
+18  A: 

It's a type issue. If you cast the 0 to unsigned it'll be fine:

unsigned mask = ~ (unsigned) 0 >> 1;
printf("%u\n", mask);

Edit per comments: or use unsigned literal notation, which is much more succinct. :)

unsigned mask = ~0u >> 1;
printf("%u\n", mask);
chaos
Or just: "unsigned mask = ~0u >> 1;" The u suffix denotes an unsigned integer.
Skizz
Ah yeah, that too.
chaos
Bingo! This question was difficult for me because I wasn't aware of the implicit type cast going on. Earlier answers didn't make that bit clear.
Jon Ericson
+3  A: 

Try this:

unsigned mask = (unsigned) ~0 >> 1;
printf("%08x\n", mask);

The RHS of the assignment is treated as a signed quantity unless you cast it, which means you were seeing sign extension without the cast. (I also changed your print statement to display the number in hex, which is easier for me to decode.)

Craig S