I suddenly noticed that i've used conversion specifier %d with type char although %d takes only type int.
How is it possible?
According to c standard, conversion specifier %d is corresponding to type int argument. And if any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
#include <stdio.h>
int main(void){
char a= 'A'; // 'A' = 65 in ASCII
printf("%c\n", a);
printf("%d\n", a);
return 0;
}
----- output -----
A
65
But whenever i compile the code like above , i always get output as intended.
Shouldn't i expect this output always?
Or, IS type char expanded to type int when passed to function's argument? So it can be 65 and i can use specifier %d
with type char?
C 2018 6.5.2.2 7 says:
… If the expression that denotes the called function [
printf
is that expression] has a type that does include a prototype [it does], the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. 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.
printf
is declared int printf(const char * restrict format, ...);
, so, in printf("%d\n", a);
, the "%d"
argument corresponds to the format
parameter, and the a
corresponds to the ...
, making it part of the trailing arguments. So the default argument promotions are performed on it. These are specified in 6.5.2.2 6:
… the integer promotions are performed on each argument, and arguments that have type
float
are promoted todouble
. These are called the default argument promotions.
The integer promotions are specified in 6.3.1.1 2:
… 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 anint
; otherwise, it is converted to anunsigned int
. These are called the integer promotions…
Thus your char
argument a
is automatically converted to an int
, so it is the correct type for %d
.