Variable arguments are used by functions in the printf family (
fprintf, etc) and others to allow a function to be called with a different number of arguments each time, hence the name varargs.
To implement functions using the variable arguments feature, use
To call functions which take a variable number of arguments, ensure there is a full prototype with the trailing ellipsis in scope:
void err_exit(const char *format, ...); for example.
|argument pointer, current position in the list of variadic arguments|
|last||name of last non-variadic function argument, so the compiler finds the correct place to start processing variadic arguments; may not be declared as a |
|type||promoted type of the variadic argument to read (e.g. |
|current argument pointer to copy|
|new argument list to be filled in|
va_copy functions are actually macros.
Be sure to always call
va_start first, and only once, and to call
va_end last, and only once, and on every exit point of the function. Not doing so may work on your system but surely is not portable and thus invites bugs.
Take care to declare your function correctly, i.e. with a prototype, and mind the restrictions on the last non-variadic argument (not
register, not a function or array type). It is not possible to declare a function that takes only variadic arguments, as at least one non-variadic argument is needed to be able to start argument processing.
va_arg, you must request the promoted argument type, that is:
shortis promoted to
unsigned shortis also promoted to
sizeof(unsigned short) == sizeof(int), in which case it is promoted to
floatis promoted to
signed charis promoted to
unsigned charis also promoted to
sizeof(unsigned char) == sizeof(int), which is seldom the case.
charis usually promoted to
int16_tare similarly promoted.
Historic (i.e. K&R) variadic argument processing is declared in
<varargs.h> but should not be used as it’s obsolete. Standard variadic argument processing (the one described here and declared in
<stdarg.h>) was introduced in C89; the
va_copy macro was introduced in C99 but provided by many compilers prior to that.