Since it isn't strongly typed I thought it just picked the right memory size and interpreted it based on the type of argument. But float and double both use %f and they are different sizes.
P.S. I can see how promotion via copying the value to a temp and casting(is this right?) might work but how does it work for scanfs/sscanf?
It doesn't differentiate. It's not possible to receive a float
as a vararg: any float
argument that you provide is first promoted to double
.
6.5.2.2/6 defines "default argument promotions", and /7 states that default argument promotions are applied to "trailing arguments", that is varargs denoted by ...
.
how does it work for scanfs/sscanf?
The %f
format for scanf
requires a pointer to float
. %lf
requires a pointer to double
, %Lf
requires a pointer to long double
.
copying the value to a temp and casting(is this right?)
If you provide a float argument, then the implementation creates a temporary of type double, initializes it with the float value, and passes this as the vararg. Casting by definition is explicit conversion by use of the cast operator -- you can cast if you like in order to make it exactly clear to the reader what's going on, but float f = 3; printf("%f", f);
is exactly the same as float f = 3; printf("%f", (double)f);
. The default argument promotion has the same meaning as the cast.