Among the library I/O functions, printf() is rather unique in that it can be called with a varying number of parameters of different types. This is permissible because the original C was not a type-checking language. Current C and C++ enforce type-checking but both still allow functions with varying number of parameters for convenience. Such functions must be declared with at least one argument, followed by 3 dots, as in
int func(int m, int n . . .) // n = last specified parameter
Inside the function, parameters can be accessed by the C library macros
void va_start(va_list ap, last); // start param list from last parameter
type va_arg(va_list ap, type); // type = next parameter type
va_end(va_list ap); // clear parameter list
We illustrate the usage of these macros by an example:
Example 9.7: Access parameter list using stdarg Macros.
/******* Example of accessing varying parameter list ********/
#include <stdio.h>
#include <stdarg> // need this for va_list type
// assume: func() is called with m integers, followed by n strings
int func(int m, int n . . .) // n = last known parameter
{
int i;
(1). va_list ap; // define a va_list ap
(2). vastart(ap, n); // start parameter list from last param n
for (i=0; i<m; i++)
(3). printf(“%d “, va_arg(ap, int)); // extract int params
for (i=0; i<n, i++)
(4). printf(“%s “, va_arg(ap, char *)) // extra char* params
(5). va_end(ap);
}
int main()
{
func(3, 2, 1, 2, 3, “test”, “ok”);
}
In the example program, we assume that the function func() will be called with 2 known parameters, int m, int n, followed by m integers and n strings.
Line (1) defines a va_list ap variable.
Line (2) starts the parameter list from the last known parameter (n).
Line (3) uses va_arg(ap, int) to extract the next m parameters as integers.
Line (4) uses va_arg(ap, char *) to extract the next n parameters as strings.
Line (5) ends the parameter list by resetting the ap list to NULL.
The reader may compile and run the example program. It should print 1 2 3 test OK.
Source: Wang K.C. (2018), Systems Programming in Unix/Linux, Springer; 1st ed. 2018 edition.