The ellipsis does not constitute a "pack" in any way that you can handle or forward directly. The only way you can manage function arguments that don't match any function parameters is via the <stdarg.h>
features.
This means that for every variable function foo
you should also always have a corresponding function vfoo
that consumes a va_list
. For example:
#include <stdarg.h>
void foo(const char * fmt, ...);
void vfoo(const char * va_list ap);
The former is typically implemented in terms of the latter:
void foo(const char * fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfoo(fmt, ap);
va_end(ap);
}
Luckily, printf
family of functions follows these rules. So when you want to farm out to a printf
function, you actually use the corresponding underlying vprintf
version:
void error(const char * fmt, ...)
{
do_stuff();
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
Of course following the same rules you should write a verror
function first and make that one call vprintf
:
void verror(const har * fmt, va_list ap)
{
do_stuff();
vfprintf(stderr, fmt, ap);
}