tags:

views:

1899

answers:

4

Hello People

On left shift of (char) 0xff by 8 and casting it to int we get -256 or 0xffffff00. Can somebody explain why this should happen?

#include <stdio.h>
int main (void)
{   
    char c = 0xff;
    printf("%d %x\n", (int)(c<<8),(int)(c<<8));
    return 0;
}

Output is

-256 ffffff00
+2  A: 

char is nothing but signed char. So char c = 0xFF will be -1 . When you left shift -1 by 8 bits you get -256.

Naveen
signedness of char is implementation defined.
Mehrdad Afshari
+7  A: 

char can be signed or unsigned - it's implementation-defined. You see these results because char is signed by default on your compiler.

For the signed char 0xFF corresponds to −1 (that's how two's complement work). When you try to shift it it is first promoted to an int and then shifted - you effectively get multiplication by 256.

So it is this code:

char c = 0xFF; // -1
int shifted = c << 8; //-256 (-1 * 256)
printf( "%d, %x", shifted, shifted );
sharptooth
+1  A: 

c is being promoted to an int before the shift operation is done. Assuming your implementation makes chars signed by default, this means you're going to get 0xffffffff, which is then shifted left to give your result.

If you make c into an unsigned char, you should get what you expect.

James Sutherland
+2  A: 

When I first looked at the problem, my initial view was that the char 'c' should be shifted left 8 bits - all 8 bits being discarded, the empty char would then be cast to an int of value 0.

A bit of research reveals Usual Unary Conversions - this is where to reduce the large number of arithmetic types, conversions are applied automatically to operands of the unary '!', '-', '~' and '*' operators, and to each of the operands of the binary '<<' and '>>' operators.

Therefore the char 'c' is converted to and int first, then shifted left, giving the answer you see.

You learn something new every day!

Beano