# Using terminator values to determine the end of va list

suggest change

With any variadic function, the function must know how to interpret the variable arguments list. The “traditional” approach (exemplified by `printf`) is to specify number of arguments up front. However, this is not always a good idea:

```/* First argument specifies the number of parameters; the remainder are also int */
extern int sum(int n, ...);

/* But it's far from obvious from the code. */
sum(5, 2, 1, 4, 3, 6)

/* What happens if i.e. one argument is removed later on? */
sum(5, 2, 1, 3, 6)  /* Disaster */```

Sometimes it’s more robust to add an explicit terminator, exemplified by the POSIX `execlp()` function. Here’s another function to calculate the sum of a series of `double` numbers:

```#include <stdarg.h>
#include <stdio.h>
#include <math.h>

/* Sums args up until the terminator NAN */
double sum (double x, ...) {
double sum = 0;
va_list va;

va_start(va, x);
for (; !isnan(x); x = va_arg(va, double)) {
sum += x;
}
va_end(va);

return sum;
}

int main (void) {
printf("%g\n", sum(5., 2., 1., 4., 3., 6., NAN));
printf("%g\n", sum(1, 0.5, 0.25, 0.125, 0.0625, 0.03125, NAN));
}```

Good terminator values:

• integer (supposed to be all positive or non-negative) — `0` or `-1`
• floating point types — `NAN`
• pointer types — `NULL`
• enumerator types — some special value