# stdarg

## NAME



           stdarg, va_start, va_arg, va_end, va_copy - variable argument
           lists
    


## LIBRARY



           Standard C library (_libc_ , _-lc_)
    


## SYNOPSIS



           **#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_**);**
    


## DESCRIPTION



           A function may be called with a varying number of arguments of
           varying types.  The include file _< stdarg.h>_ declares a type
           _va_list_ and defines three macros for stepping through a list of
           arguments whose number and types are not known to the called
           function.
    
           The called function must declare an object of type _va_list_ which
           is used by the macros **va_start**(), **va_arg**(), and **va_end**().
    
       **va_start()**
           The **va_start**() macro initializes _ap_ for subsequent use by **va_arg**()
           and **va_end**(), and must be called first.
    
           The argument _last_ is the name of the last argument before the
           variable argument list, that is, the last argument of which the
           calling function knows the type.
    
           Because the address of this argument may be used in the **va_start**()
           macro, it should not be declared as a register variable, or as a
           function or an array type.
    
       **va_arg()**
           The **va_arg**() macro expands to an expression that has the type and
           value of the next argument in the call.  The argument _ap_ is the
           _va_list ap_ initialized by **va_start**().  Each call to **va_arg**()
           modifies _ap_ so that the next call returns the next argument.  The
           argument _type_ is a type name specified so that the type of a
           pointer to an object that has the specified type can be obtained
           simply by adding a * to _type_.
    
           The first use of the **va_arg**() macro after that of the **va_start**()
           macro returns the argument after _last_.  Successive invocations
           return the values of the remaining arguments.
    
           If there is no next argument, or if _type_ is not compatible with
           the type of the actual next argument (as promoted according to the
           default argument promotions), random errors will occur.
    
           If _ap_ is passed to a function that uses **va_arg(**_ap_**,**_type_**),** then the
           value of _ap_ is undefined after the return of that function.
    
       **va_end()**
           Each invocation of **va_start**() must be matched by a corresponding
           invocation of **va_end**() in the same function.  After the call
           **va_end(**_ap_**)** the variable _ap_ is undefined.  Multiple traversals of
           the list, each bracketed by **va_start**() and **va_end**() are possible.
           **va_end**() may be a macro or a function.
    
       **va_copy()**
           The **va_copy**() macro copies the (previously initialized) variable
           argument list _src_ to _dest_.  The behavior is as if **va_start**() were
           applied to _dest_ with the same _last_ argument, followed by the same
           number of **va_arg**() invocations that was used to reach the current
           state of _src_.
    
           An obvious implementation would have a _va_list_ be a pointer to the
           stack frame of the variadic function.  In such a setup (by far the
           most common) there seems nothing against an assignment
    
               va_list aq = ap;
    
           Unfortunately, there are also systems that make it an array of
           pointers (of length 1), and there one needs
    
               va_list aq;
               *aq = *ap;
    
           Finally, on systems where arguments are passed in registers, it
           may be necessary for **va_start**() to allocate memory, store the
           arguments there, and also an indication of which argument is next,
           so that **va_arg**() can step through the list.  Now **va_end**() can free
           the allocated memory again.  To accommodate this situation, C99
           adds a macro **va_copy**(), so that the above assignment can be
           replaced by
    
               va_list aq;
               va_copy(aq, ap);
               ...
               va_end(aq);
    
           Each invocation of **va_copy**() must be matched by a corresponding
           invocation of **va_end**() in the same function.  Some systems that do
           not supply **va_copy**() have **__va_copy** instead, since that was the
           name used in the draft proposal.
    


## ATTRIBUTES



           For an explanation of the terms used in this section, see
           attributes(7).
           ┌──────────────────────────────┬───────────────┬─────────────────┐
           │ **Interface** │ **Attribute** │ **Value** │
           ├──────────────────────────────┼───────────────┼─────────────────┤
           │ **va_start**(), **va_end**(),        │ Thread safety │ MT-Safe         │
           │ **va_copy**()                    │               │                 │
           ├──────────────────────────────┼───────────────┼─────────────────┤
           │ **va_arg**()                     │ Thread safety │ MT-Safe race:ap │
           └──────────────────────────────┴───────────────┴─────────────────┘
    


## STANDARDS



           C11, POSIX.1-2008.
    


## CAVEATS



           Unlike the historical **varargs** macros, the **stdarg** macros do not
           permit programmers to code a function with no fixed arguments.
           This problem generates work mainly when converting **varargs** code to
           **stdarg** code, but it also creates difficulties for variadic
           functions that wish to pass all of their arguments on to a
           function that takes a _va_list_ argument, such as vfprintf(3).
    


## EXAMPLES



           The function _foo_ takes a string of format characters and prints
           out the argument associated with each format character based on
           the type.
    
           #include <stdio.h>
           #include <stdarg.h>
    
           void
           foo(char *fmt, ...)   /* '...' is C syntax for a variadic function */
    
           {
               va_list ap;
               int d;
               char c;
               char *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 */
                       /* need a cast here since va_arg only
                          takes fully promoted types */
                       c = (char) va_arg(ap, int);
                       printf("char %c\n", c);
                       break;
                   }
               va_end(ap);
           }
    


* * *