Gooday2die
Gooday2die

Reputation: 109

Why is a number sign-extended when it is cast to an unsigned type?

I was studying how C stores data in memory by bit patterns.
However I have confronted some issues when it comes to printf formatting.

I have saved a variable as -10 (I do understand two's complement) and another variable as 246. Those two variables have bit patterns of 11110110 (which is 0xF6).

I was trying to print out a value using the unsigned int hexadecimal format in printf.

char a = -10; 
unsigned char b = 246;

printf("a : %x , b : %x\n" , (unsigned int) a, (unsigned int) b);
//a : fffffff6 , b : f6

Both integers have the same bit pattern of 0xF6. However, if I do perform type casting into unsigned int, the result varies. The result is 0xFFFFFFF6 for a, while b remains the same.

For a signed character, it seems to me that type casting process made the unsigned char into an integer and filled all the empty bits with 1.

Is this due to their signedness? Or is this just Undefined Behavior?

Upvotes: 4

Views: 2156

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

In this expression

(unsigned int) a

the integer promotions are applied to the object a.

From the C Standard (6.3.1.1 Boolean, characters, and integers)

2 The following may be used in an expression wherever an int or unsigned int may be used:

— An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.

— A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions.

and

3 The integer promotions preserve value including sign. As discussed earlier, whether a ‘‘plain’’ char is treated as signed is implementation-defined.

If you want that in the result object after casting the character object would be represented as having the type unsigned char then you have to write

(unsigned char) a

As the value of the promoted expression (unsigned char) a can be represented in the type unsigned int then the second cast (to unsigned int) is not required. The C Standard allows to use arguments pf the type int instead of the type unsigned int if the value is represented in the both types. You could just write

printf("a : %x , b : %x\n" , (unsigned char) a, (unsigned int) b);

Upvotes: 5

Related Questions