4.7 Signal Handling  -< ANSI C Rationale  -> 4.9 Input/Output                    Index 

4.8  Variable Arguments  <stdarg.h>

For a discussion of argument passing issues, see §3.7.1

These macros, modeled after the UNIX <varargs.h> macros, have been added to enable the portable implementation in C of library functions such as printf and scanf (see §4.9.6).  Such implementation could otherwise be difficult, considering newer machines that may pass arguments in machine registers rather than using the more traditional stack-oriented methods. 

The definitions of these macros in the Standard differ from their forebears: they have been extended to support argument lists that have a fixed set of arguments preceding the variable list. 

va_start and va_arg must exist as macros, since va_start uses an argument that is passed by name and va_arg uses an argument which is the name of a data type.  Using #undef on these names leads to undefined behavior

The va_list type is not necessarily assignable.  However, a function can pass a pointer to its initialized argument list object, as noted below.

4.8.1  Variable argument list access macros

4.8.1.1  The va_start macro

va_start must be called within the body of the function whose argument list is to be traversed.  That function can then pass a pointer to its va_list object ap to other functions to do the actual traversal.  (It can, of course, traverse the list itself.) 

The parmN argument to va_start is an aid to writing conforming ANSI C code for existing C implementations.  Many implementations can use the second parameter within the structure of existing C language constructs to derive the address of the first variable argument.  (Declaring parmN to be of storage class register would interfere with use of these constructs; hence the effect of such a declaration is undefined behavior Other restrictions on the type of parmN are imposed for the same reason.)  New implementations may choose to use hidden machinery that ignores the second argument to va_start, possibly even hiding a function call inside the macro. 

Multiple va_list variables can be in use simulaneously in the same function; each requires its own calls to va_start and va_end

4.8.1.2  The va_arg macro

Changing an arbitrary type name into a type name which is a pointer to that type could require sophisticated rewriting.  To allow the implementation of va_arg as a macro, va_arg need only correctly handle those type names that can be transformed into the appropriate pointer type by appending a *, which handles most simple cases.  (Typedefs can be defined to reduce more complicated types to a tractable form.)  When using these macros it is important to remember that the type of an argument in a variable argument list will never be an integer type smaller than int, nor will it ever be float (See §3.5.4.3.) 

va_arg can only be used to access the value of an argument, not to obtain its address. 

4.8.1.3  The va_end macro

va_end must also be called from within the body of the function having the variable argument list.  In many implementations, this is a do-nothing operation; but those implementations that need it probably need it badly. 


4.7 Signal Handling  -< ANSI C Rationale  -> 4.9 Input/Output                    Index