I had this question while reading C++ Standard, but it basically just references C Standard, so I guess this question applies to both languages.
From [cstdarg.syn]
If the parameter parmN is of a reference type, or of a type that is not compatible with the type that results when passing an argument for which there is no parameter, the behavior is undefined.
I dont understand the rule about "compatible" types. Compatible types are pretty much the same types in C, so what does this rule means exactly? parmN cant be float, bool, char, short?
int add_nums(short count, ...)
{
int result = 0;
std::va_list args;
va_start(args, count); // undefined behavior ?
for (short i = 0; i < count; ++i) {
result += va_arg(args, int);
}
va_end(args);
return result;
}
Also, what is the reasoning behind this rule? I get how parmN cant be reference, but I dont see how its type is related to types of variadic arguments.
The rule regarding types has to do with promotion of arguments.
For variadic arguments, passed arguments of type
floatare promoted todoubleand integer arguments with a type smaller thanintare promoted tointorunsigned int. This means thatva_argcannot expect arguments of these types, otherwise you trigger undefined behavior.This behavior with regard to variadic functions is documented in section 6.5.2.2p7 of the C11 standard:
And the term default argument promotions is defined in 6.5.2.2p6: