Puede usar cualquier valor que desee para marcar el final de la lista de argumentos, siempre que sepa lo suficiente sobre ello desde la lista de argumentos. El compilador normalmente no verificará que el valor que elija en realidad se pase cuando se llama a la función, por lo que deberá tener cuidado con ello.
Esencialmente usted acaba de crear una función variable de la manera habitual, y dentro de la función deja de leer los argumentos cuando lee uno que coincida con su centinela - no hay nada particularmente especial que hacer, pero necesita saber qué tipos de argumentos para leer.
Por ejemplo:
#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;
}
... contará todos sus argumentos que se producen antes 5
. Sin embargo, pueden pasar cosas malas si no lo pasa 5
en algún lugar de la lista, o si le pasa argumentos que no son int
.
Otro ejemplo con punteros, donde un ganglio centinela se pasa como la primera, y de nuevo como el último, el argumento:
/* Count arguments, excluding the first, until the first occurs again */
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;
}
En cuanto a la creación de dicha función, claramente usted puede hacerlo. No sé de ninguna extensión de GNU para verificar que los argumentos sean correctos para los esquemas varargs arbitrarios. Ni siquiera tienen un atributo para marcar un parámetro como un "recuento" de cuántos argumentos se dieron para que el compilador pueda verificar si lo hicieron bien. –