stdarg.h
is a header in the C standard library of the C programming language that allows functions to accept an indefinite number of arguments. It provides facilities for stepping through a list of function arguments of unknown number and type. cstdarg
.
The contents of stdarg.h
are typically used in vprintf
The C programming language provides many standard library functions for file input and output. These functions make up the bulk of the C standard library header . The functionality descends from a "portable I/O package" written by Mike Lesk ...
) called by variadic functions.
Declaring variadic functions
Variadic functions are functions which may take a variable number of arguments and are declared with anprintf
The printf format string is a control parameter used by a class of functions in the input/output libraries of C and many other programming languages. The string is written in a simple template language: characters are usually copied literal ...
. A typical declaration is
Defining variadic functions
The same syntax is used in a definition:stdarg.h types
stdarg.h macros
Accessing the arguments
To access the unnamed arguments, one must declare a variable of typeva_list
in the variadic function. The macro va_start
is then called with two arguments: the first is the variable declared of the type va_list
, the second is the name of the last named parameter of the function. In C23 the second argument will be optional and will not be evaluated. After this, each invocation of the va_arg
macro yields the next argument. The first argument to va_arg
is the va_list
and the second is the type of the next argument passed to the function. Finally, the va_end
macro must be called on the va_list
before the function returns. (It is not required to read in all the arguments.)
va_copy
, which can duplicate the state of a va_list
. The macro invocation va_copy(va2, va1)
copies va1
into va2
.
There is no mechanism defined for determining the number or types of the unnamed arguments passed to the function. The function is simply required to know or determine this somehow, the means of which vary. Common conventions include:
* Use of a printf
The printf format string is a control parameter used by a class of functions in the input/output libraries of C and many other programming languages. The string is written in a simple template language: characters are usually copied literal ...
or scanf
A scanf format string (''scan f''ormatted) is a control parameter used in various functions to specify the layout of an input string. The functions can then divide the string and translate into values of appropriate data types. String scannin ...
-like format string with embedded specifiers that indicate argument types.
* A Passing unnamed arguments to other calls
Because the size of the unnamed argument list is generally unknown (the calling conventions employed by most compilers do not permit determining the size of the unnamed argument block pointed at byva_list
inside the receiving function), there is also no reliable, generic way to forward the unnamed arguments into another variadic function. Even where determining the size of the argument list is possible by indirect means (for example, by parsing the format string of fprintf()
), there is no portable way to pass the dynamically determined number of arguments into the inner variadic call, as the number and size of arguments passed into such calls must generally be known at compile time. To some extent, this restriction can be relaxed by employing v
-prefixed alternative versions which accept a ''reference'' to the unnamed argument list (i.e. an initialized va_list
variable) instead of the unnamed argument list itself. For example, vfprintf()
is an alternate version of fprintf()
expecting a va_list
instead of the actual unnamed argument list. A user-defined variadic function can therefore initialize a va_list
variable using va_start
and pass it to an appropriate standard library function, in effect passing the unnamed argument list by reference instead of doing it by value. Because there is no reliable way to pass unnamed argument lists by value in C, providing variadic va_list
instead is considered a bad programming practice.
Type safety
Some C implementations provide C extensions that allow the compiler to check for the proper use of format strings and sentinels. Barring these extensions, the compiler usually cannot check whether the unnamed arguments passed are of the type the function expects, or convert them to the required type. Therefore, care should be taken to ensure correctness in this regard, sinceint *
, then a null pointer should be passed as (int *)NULL
. Writing just NULL
would result in an argument of type either int
or void *
, neither of which is correct. Another consideration is the default argument promotions applied to the unnamed arguments. A float
will automatically be promoted to a double
. Likewise, arguments of types narrower than an int
will be promoted to int
or unsigned int
. The function receiving the unnamed arguments must expect the promoted type.
GCC has an extension that checks the passed arguments:
Example
5 2 14 84 97 15 84 51 1To call other var args functions from within your function (such as sprintf) you need to use the var arg version of the function (vsprintf in this example):
varargs.h
Outdated versions ofvarargs.h
, which dates from before the standardization of C and provides functionality similar to stdarg.h
. This header is part of neither ISO C nor POSIX. The file, as defined in the second version of the Single UNIX Specification, simply contains all of the functionality of C89 stdarg.h
, with the exceptions that:
* it cannot be used in standard C new-style definitions
* the given argument may be omitted (standard C requires at least one argument)
The interface is also different. For example, one would instead write:
varargs.h
requires old-style function definitions because of the way the implementation works. Conversely, it is not possible to mix old-style function definitions with stdarg.h
.
References
{{CProLang, state=expanded Articles with example C code C standard library headers