According to the standard, to access the unnamed arguments it can be through a variable of type va_list in the variadic function, with macro va_start also provided as the last named parameter of the function. In C23 the second argument is optional and will not be evaluated. After this, each invocation of the va_arg macro yields the next argument. The first argument to va_arg is the va_list and the second is the type of the next argument passed to the function. As the last step, the va_end macro must be called on the va_list before the function returns. Note that it is not required to read in all the arguments.
C99 provides an additional macro, va_copy, which can duplicate the state of a va_list. The macro invocation va_copy(va2, va1) copies va1 into va2. There is no defined method for counting or classifying the unnamed arguments passed to the variadic function. The function should simply determine this somehow, the means of which vary. Common conventions include: • Use of a
printf or
scanf-like format string with embedded specifiers that indicate argument types. • A
sentinel value at the end of the variadic arguments. • A count argument indicating the number of variadic arguments.
Passing unnamed arguments to other calls As the size of the unnamed argument list is generally unknown, the calling conventions employed by most compilers do not permit determining the size of the unnamed argument block pointed at by va_list inside the receiving function. As a result there is also no reliable, generic way to forward the unnamed arguments into another variadic function. Even where determining the size of the argument list is possible by indirect means (for example, by parsing the format string of fprintf()), there is no portable way to pass the dynamically determined number of arguments into the inner variadic call, as the number and size of arguments passed into such calls must generally be known at compile time. To some extent, this restriction can be relaxed by employing
variadic macros instead of variadic functions. Additionally, most standard library procedures provide v-prefixed alternative versions which accept a
reference to the unnamed argument list (i.e. an initialized va_list variable) instead of the unnamed argument list itself. For example, vfprintf() is an alternate version of fprintf() expecting a va_list instead of the actual unnamed argument list. A user-defined variadic function can therefore initialize a va_list variable using va_start and pass it to an appropriate standard library function, in effect passing the unnamed argument list by reference instead of doing it by value. Because there is no reliable way to pass unnamed argument lists by value in C, providing variadic
API functions without also providing equivalent functions accepting va_list instead is considered a bad programming practice. ==Type safety==