Yes, float arguments to variadic function are promoted to double.
The draft C99 standard section 6.5.2.2
Function calls says:
[...]and arguments that
have type float are promoted to double. These are called the default argument
promotions.[...]
from the draft C++ standard section 5.2.2
Function call:
[...]a floating point type that is subject to the floating point
promotion (4.6), the value of the argument is converted to the
promoted type before the call. [...]
and section 4.6
:
A prvalue of type float can be converted to a prvalue of type double. The value is unchanged
cppreference covers the default conversions for variadic function in C++ well:
- std::nullptr_t is converted to void*
- float arguments are converted to double as in floating-point promotion
- bool, char, short, and unscoped enumerations are converted to int or wider integer types as in integer promotion
We can see in C and presumably in C++ this conversion was kept around for compatibility with K&R C, from Rationale for International Standard—Programming Languages—C (emphasis mine):
For compatibility with past practice, all argument promotions occur as
described in K&R in the absence of a prototype declaration, including
the not always desirable promotion of float to double.
char
is promoted toint
, sochar c=127; printf("%d", c);
works correctly too. – Sluffshort
does not necessarily run faster thanint
because a promotion ofshort
toint
happens with every arithmetic calculation. – Slufffloat
values are not always converted todouble
when passed to a function, but they are when passed as trailing arguments to a var-args function likeprintf
. – JenniejenniferC Primer Plus
turns up a PDF of the fifth edition where the actual quote is "That's because C automatically expands type float values to type double when they are passed as arguments to any function, such as printf(), that doesn't explicitly prototype the argument type." – Eppesint
as well but the point stands forchar
(and a few 68k compilers when used to target older chip reversions). – Sackbutsigned short
calculation with runtime operation32000 + 15000 - 20000
the intermediate sum will overflow and cause undefined behaviour, unless promoted toint
. – Sluffvoid foo(f);
would only be a declaration, not a prototype. – Eppestypically
. It is a trick performed by all compilers targetting 8-bit embedded architectures systems which I have used. In practice an optimizing compiler which doesn't know the properties of the architecture it is optimizing for would be a strange beast, and C compilers straying outside of two's complement integer representations are similarly exceedingly rare. – Sackbut