Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

printf type promotion and sign extension

Tags:

c

printf

I am confused about how type promotion happens in case of printf and in general. I tried the following code

unsigned char uc = 255
signed char sc = -128

printf("unsigned char value = %d \n", uc);
printf("signed char value = %d \n", sc);

This gives the following output :

unsigned char value = 255
signed char value = -128

This has left me wondering about how promotion actually takes place and whether a sign extension happens or not. If a sign extension is done then the value 255 should be printed as negative value (-128 remaining the same) and if no sign extension is done then -128 should have been printed as a positive value (255 remaining the same). Please explain.

like image 938
vjain27 Avatar asked Mar 15 '12 08:03

vjain27


3 Answers

If a sign extension is done then the value 255 should be printed as negative value

This is where you're wrong - all values of type unsigned char including 255, can be represented in a int, so the promotion to int from unsigned char just happens without any funny business.

Where problems occur is when a signed value must be converted (which is a different thing than promotion, and occurs to create a common type for operands) to an unsigned value. If that signed type has a negative value, then the conversion to an unsigned type will change the value.

In summary, integer promotion preserves value (including sign), conversion can change value.

like image 131
Michael Burr Avatar answered Sep 27 '22 22:09

Michael Burr


A va_arg function has no information on the expected type for the ... part. Therefore the promotion rules for functions as declared without prototype apply. This means that all types that are shorter than int are promoted to int or unsigned directly. So your printf function never sees an (un)signed char.

like image 43
Jens Gustedt Avatar answered Sep 27 '22 23:09

Jens Gustedt


Sign extension is done. But you can't sign extend an unsigned char because it has no sign bit. The whole point of sign extension is to keep the value the same. Or, if you prefer to think of it this way, every unsigned variable has an implied zero sign bit. So when it's sign-extended to a larger signed type, the sign bit should be zero in the larger type.

like image 32
David Schwartz Avatar answered Sep 27 '22 21:09

David Schwartz