... I guess I can assume from the existance of vprintf, that
there is no way to pass a va_list directly to printf itself ?
The conclusion here is correct -- you must call vprintf() rather
than printf() -- but the premise itself is faulty. In the past,
some implementations of printf() had a "%r" format that meant (more
or less) "the corresponding argument is a va_list that you should
switch to for all subsequent arguments". (In fact, at least one
%r directive took a format followed by a va_list, and worked them
in a sort of recursive fashion, hence the 'r' could be said to
stand for "recursive". Since %r was never standardized, other
printf()s that handled %r may have done other things.)
(To prove the need for the vprintf() family, you can simply read
the definition for printf() in the appropriate C Standard, and see
that there is no standard directive that takes a va_list.)
As a general rule, if you ever write your own variadic function:
TYPE my_variadic_function(T1 fixed1, T2 fixed2, ...) {
... some code will go here ...
}
you should begin by writing its entire guts as a "v"-prefixed
variant:
TYPE vmy_variadic_function(T1 fixed1, T2 fixed2, va_list ap) {
... the guts of the function ...
return whatever;
}
and then write the "wrapper" as the relatively short:
TYPE my_variadic_function(T1 fixed1, T2 fixed2, ...) {
TYPE ret;
va_list ap;
va_start(ap, fixed2);
ret = vmy_variadic_function(fixed1, fixed2, ap);
va_end(ap);
return ret;
}
That way, even though you (presumably) do not need it yourself yet,
the "v"-prefixed variant exists for whoever -- possibly you --
discovers a need for it later, in the same way that vprintf()
existed for you when you recently discovered a need for it.
The original C89 standard failed to provide a vscanf() family.
This is fixed in C99.