Variadic functions provide the ability to specify a variable number of arguments to a function, but they can be problematic. Variadic functions contain an implicit contract between the function writer and the function user that must be made to establish how many arguments are passed on an invocation ([Seacord]). If care is not exercised when invoking a variadic function to ensure that it knows when to stop processing arguments, the result may be an unbounded stack crawl possibly resulting in abnormal program termination.
In the following code example, a variadic function called average()
is used to determine the average value of its passed integer arguments. The function will stop processing arguments when it sees that the argument is -1
.
int average(int first, ...) { int count = 0; int sum = 0; int i = first; va_list marker; va_start(marker, first); while (i != -1) { sum += i; count++; i = va_arg(marker, int); } va_end(marker); return(sum ? (sum / count) : 0); }
However, if the function is called as follows:
int avg = average(1, 4, 6, 4, 1);
The omission of the -1
terminating value means that on some architectures, the function will continue to grab values from the stack until it either hits a -1
by coincidence, or until it is terminated.