Trying to turn off the MSB with all other bits on.
unsigned char a = ~0 << 1 >> 1;
printf("a: %d\n", a);
unsigned char b = ~0;
b <<= 1;
b >>= 1;
printf("b: %d\n", b);
The printout gives:
a: 255
b: 127
Integer promotion rules apply.
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand.
The RHS of the initialization:
unsigned char a = ~0 << 1 >> 1;
converts 0
to int
, then does bitwise left and right shifts, and then finally the assignment converts the result to unsigned char
. This means that the result will be 255 (assuming CHAR_BIT == 8
). Technically, you have undefined behaviour:
The result of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are filled with zeros. IfE1
has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
You would avoid undefined behaviour if you used:
unsigned char a = ~0U << 1 >> 1;
The 'multiple assignments' version (avoiding undefined behaviour) is equivalent to:
unsigned char a = (unsigned char)(~0U << 1) >> 1;
which truncates the result of the left shift before re-promoting the type for the right shift, and would yield 127 as the result (still assuming CHAR_BIT == 8
).