Format specifier for unsigned char

The correct one is*:

printf("%d",x);

This is because of default argument promotions as printf() is variadic function. This means that unsigned char value is always promoted to int.

From N1570 (C11 draft) 6.5.2.2/6 Function calls (emphasis mine going forward):

If the expression that denotes the called function has a type that
does not include a prototype, the integer promotions are performed on
each argument, and arguments that have type float are promoted to
double. These are called the default argument promotions.

and 6.5.2.2/7 subclause tells:

The ellipsis notation in a function prototype declarator causes
argument type conversion to stop after the last declared parameter.
The default argument promotions are performed on trailing arguments.

These integer promotions are defined in 6.3.1.1/2 Boolean, characters, and integers:

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.

This quote answers your second question of unsigned short (see comment below).


* with exception to more than 8 bits unsigned char (e.g. it might occupy 16 bit), see @chux’s answer.

Leave a Comment