For a discussion of argument passing issues, see §3.7.1.
modeled after the UNIX
have been added to enable the portable implementation in C
of library functions such as
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_arg must exist as macros,
va_start uses an argument that is passed by name and
va_arg uses an argument which is the name of a data type.
on these names leads to undefined behavior.
va_list type is not necessarily assignable.
However, a function can pass a pointer to its initialized argument
list object, as noted below.
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
to other functions to do the actual traversal.
(It can, of course, traverse the list itself.)
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
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
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.
va_list variables can be in use simulaneously
in the same function;
each requires its own calls to
Changing an arbitrary
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
nor will it ever be
va_arg can only be used to access the value of an argument,
not to obtain its address.
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.