Q:

How do the printf function in C get the size of every parameter in the variable parameters list?

Recently, i try to understand the detailed implement of printf in C,
i have understand the usage of va_start, va_arg and va_end,
but one question i always can not understand is how the printf get the size of every parameters in the parameter list though it knows the output format(%d,%c and so on). give one example to show my question more visually：
int a = 27;
char b = 19;
printf("%d, %c", a, b);

the detailed implement of printf that i know is that:
step 1: it gets the pointer to the start of variable parameters by using the macros va_start(args, format), format is char pointer to the below string "%d, %c", args is the pointer to start of the variable parameters located in the stack;
step 2: it gets the value of every parameters by using the macros va_arg(args, int), and then output the parameters according to the format string;
step 3:using va_end(args), clear the args pointer;
the critical point i can not understand is that when the function want to output the value of a, why it can knows using "int" as the second parameters of macros va_arg ? the detailed implement of macros va_arg is to get data according to the args pointer to the stack, the length of getting data depends on the second parameters, here it's int, why do it inject "int" to va_arg rather than the "char" or "long int", what condition let it know inject "int" ?
the condition is the format string?
in the above example, it can not get the size of a, only depends on "%d".
Thanks a lot for your explaination in advance.

A:

... to output the value of a, why it can knows using "int" as the second parameters of macros va_arg ?

Because you told it so.
The %d conversion requires an int as input, so printf assumes you passed the correct type.
If you get this wrong (ie, you pass a char for a %d conversion specifier), it will break and it's your fault.
The relevant text from my local manpage is:

The arguments must correspond properly (after type promotion) with the conversion specifier.

And this reference has a detailed table describing the required argument type for each conversion specifier. Some compilers or static analyzers can warn you if your argument types don't match your format string, but it is always ultimately your responsibility to just code correctly.

