There is a special rule for functions with variable-length argument lists, like printf
. In the variable-length portion of the argument list, all integral arguments smaller than int
are promoted to int
, and float
is promoted to double
. So it turns out it's perfectly fine to print a character (or a short
) using %d
.
These default argument promotions end up accounting for a number of anomalies in printf
. You might think that the correct format specifiers for char
, short
, int
, float
, and double
are %hhd
, %hd
, %d
, %f
, and %lf
, respectively. But in fact you can get away with %d
, %d
, %d
, %f
, and %f
. printf
basically ignores the l
modifier for floating point, and it seems to ignore the h
modifier for integers. (Actually h
can make a difference in obscure cases, as chux explains in a comment.)