You can use any value that you want to mark at the end of the argument list, provided that you know enough about it in the argument list. The compiler usually does not verify that the value you select is actually passed when the function is called, so you need to take care of this.
Basically, you simply create a variable function in the usual way, and inside the function you stop reading the arguments when you read the one that matches your sentinel - there is nothing special to do, but you need to know what types of arguments to read.
For example:
#include <stdarg.h> /* Count arguments up to the number 5 */ int countArgsTilFive(int first, ...) { int res = 1; va_list ap; if (first == 5) return 0; va_start(ap,first); while (va_arg(ap,int) != 5) res++; va_end(ap); return res; }
... will count all its arguments that occur before 5 . Bad things can happen if you don't pass it 5 somewhere in the list, or pass arguments that are not int .
Another example with pointers, where the guard symbol node is passed as the first and again as the last argument:
int countPtrs(void *sentinel, ...) { int res = 0; va_list ap; va_start(ap,sentinel); while (va_arg(ap,void *) != sentinel) res++; va_end(ap); return res; }
Dmitri
source share