Provided by: manpages-es_1.55-10_all bug

NOMBRE

       stdarg - lista de argumentos variable

SINOPSIS

       #include <stdarg.h>

       void va_start(va_list ap, last);
       type va_arg(va_list ap, type);
       void va_end(va_list ap);
       void va_copy(va_list dest, va_list src);

DESCRIPCIÓN

       Una  función  podría  ser llamada con un número de argumentos variable de tipos igualmente
       variables. El fichero de cabecera (include) stdarg.h declara un tipo va_list y define tres
       macros  para  moverse  a  través  de  una  lista  de  argumentos cuyo número y tipo no son
       conocidos para la función llamada.

       Dicha función debe declarar un objeto de tipo va_list el cual es utilizado por las  macros
       va_start, va_arg y va_end.

   va_start
       La  macro  va_start  inicializa  ap  para su uso posterior por va_arg y va_end, y debe ser
       llamada en primer lugar.

       El parámetro last es el nombre del último  parámetro  antes  de  la  lista  de  argumentos
       variables, es decir, el último parametro sobre el cual la función llamada conoce el tipo.

       Dado  que  la  dirección  de  este  parámetro puede ser utilizada por la macro va_start no
       debería ser declarado como una variable de registro, como una función ni como un array.

   va_arg
       La macro va_arg expande una expresión  que  contiene  el  tipo  y  el  valor  del  próximo
       argumento  empleado  en  la  llamada.  El  parámetro  ap es el va_list ap inicializado por
       va_start.  Cada llamada a va_arg modifica ap por tanto la siguiente llamada  devolverá  el
       próximo  argumento.  El  parámetro type es el nombre de un tipo especificado para que para
       que el tipo de un puntero a un objeto que es de dicho tipo pueda ser obtenido  simplemente
       añadiendo un * a type.

       El  primer  uso  de  la  macro va_arg despues de va_start devuelve el argumento tras last.
       Invocaciones sucesivas devolverán los valores del resto de los argumentos.

       Si no hay próximo argumento, o si type no es compatible con el tipo del próximo argumento,
       se producirán errores impredecibles.

       Si  ap  es  pasado  a una función que usa va_arg(ap,type), el valor de ap es indefinido al
       regresar dicha función.

   va_end
       A cada invocación de va_start le corresponde una invocación de va_end en la misma función.
       Después  de  la  llamada  a  va_end(ap)  la variable ap es indefinida. Son posibles varios
       recorridos de la lista, cada uno comprendido entre va_start y va_end.   va_end  puede  ser
       una macro o una función.

   va_copy
       Una  implementación  obvia  haría  que  va_list  fuera  un  puntero al marco de pila de la
       función.  En tal caso (con mucho el más común) no hay ningún problema con  una  asignación
       del tipo
                   va_list aq = ap;
       Desafortunadamente,  también hay sistemas que lo implementan como un array de punteros (de
       longitud 1), y por tanto es necesario
                   va_list aq;
                   *aq = *ap;
       Finalmente, en sistemas donde los parámetros son pasados en registros, puede ser necesario
       para  va_start reservar memoria y almacenar ahí los parámetros junto con una indicación de
       qué parámetro es el siguiente, con el fin de que va_arg pueda  recorrer  la  lista.  Ahora
       va_end puede liberar de nuevo la memoria reservada.  Para acomodarse a esta situación, C99
       añade una macro va_copy, para que la asignación de arriba puede reemplazarse por
                   va_list aq;
                   va_copy(aq, ap);
                   ...
                   va_end(aq);
       A cada invocación de va_copy le corresponde una invocación de va_end en la misma  función.
       Algunos  sistemas que no proporcionan va_copy tienen __va_copy en su lugar, puesto que ese
       fue el nombre usado en la propuesta inicial.

EJEMPLOS

       La función foo toma una cadena de caracteres de formato e imprime  el  argumento  asociado
       con cada caracter de formato basado en el tipo.
              #include <stdio.h>
              #include <stdarg.h>

              void foo(char *fmt, ...) {
                   va_list ap;
                   int d;
                   char c, *p, *s;

                   va_start(ap, fmt);
                   while (*fmt)
                        switch(*fmt++) {
                        case 's':           /* string */
                             s = va_arg(ap, char *);
                             printf("string %s\n", s);
                             break;
                        case 'd':           /* int */
                             d = va_arg(ap, int);
                             printf("int %d\n", d);
                             break;
                        case 'c':           /* char */
                             /* Aquí es necesaria una conversión forzada
                              * de tipos ya que va_arg sólo toma tipos
                              * totalmente `ascendidos'.
                              */
                             c = (char) va_arg(ap, char);
                             printf("char %c\n", c);
                             break;
                        }
                   va_end(ap);
              }

CONFORME A

       Las  macros  va_start,  va_arg  y  va_end  concuerdan con ANSI X3.159-1989 (``C89'').  C99
       define la macro va_copy.

COMPATIBILIDAD

       Estas macros no son compatibles  con  las  macros  históricas  que  reemplazan.  Se  puede
       encontrar una versión compatible "hacia atrás" en el fichero de cabecera varargs.h.

COMPARACIÓN

       La configuración histórica es:
              #include <varargs.h>

              void foo(va_alist) va_dcl {
                   va_list ap;

                   va_start(ap);
                   while(...) {
                        ...
                        x = va_arg(ap, type);
                        ...
                   }
                   va_end(ap);
              }
       En  algunos  sistemas, va_end contiene un carácter de cierre '}' que se corresponde con un
       '{' en va_start, con lo que ambas macros deben aparecer en la  misma  función,  y  de  una
       manera que lo permita.

FALLOS

       Al  contrario  que  las  macros varargs, las macros stdarg no permiten a los programadores
       codificar  una  función  con  argumentos   variables.   Este   problema   genera   trabajo
       principalmente  cuando  se  convierte  código  basado en varargs a stdarg pero además crea
       dificultades a las funciones que quieran pasar todos sus argumentos  en  una  función  que
       toma una lista de argumentos va_list, como vfprintf(3).

                                         14 octubre 2001                                STDARG(3)