Stdarg.h
From Wikipedia, the free encyclopedia
C++ Standard Library headers |
C Standard Library headers |
---|
assert.h |
complex.h |
ctype.h |
errno.h |
fenv.h |
float.h |
inttypes.h |
iso646.h |
limits.h |
locale.h |
math.h |
setjmp.h |
signal.h |
stdarg.h |
stdbool.h |
stddef.h |
stdint.h |
stdio.h |
stdlib.h |
string.h |
tgmath.h |
time.h |
wchar.h |
wctype.h |
- The correct title of this article is stdarg.h. The initial letter is shown capitalized due to technical restrictions.
<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. C++ provides this functionality in the header <cstdarg>
; the C header, though permitted, is deprecated in C++.
The contents of <stdarg.h>
are typically used in variadic functions, though they may be used in other functions (for example, vprintf
) called by variadic functions.
Contents |
[edit] Declaring variadic functions
Variadic functions are functions which may take a variable number of arguments and are declared with an elipsis in place of the last parameter. An example of such a function is printf
. A typical declaration is
int check(int a, double b, ...);
Variadic functions must have at least one named parameter, so, for instance,
char *wrong(...);
is not allowed in C. (In C++, such a declaration is permitted, but useless.)
In C, a comma must precede the ellipsis; in C++, it is optional.
[edit] stdarg.h types
Name | Description | Compatibility |
---|---|---|
va_list |
type for iterating arguments | C89 |
[edit] stdarg.h macros
Name | Description | compatibility |
---|---|---|
va_start |
Start iterating arguments with a va_list | C89 |
va_arg |
Retrieve an argument | C89 |
va_end |
Free a va_list | C89 |
va_copy |
Copy contents one va_list to another | C99 |
[edit] Accessing the arguments
To access the unnamed arguments, one must declare a variable of type va_list
in the variadic function. The macro va_start
is then called with two arguments: the first is the va_list
, the second is the name of the last named parameter of the function. 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.)
C99 provides an additional macro, 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 or scanf-like format string with embedded specifiers that indicate argument types.
- A sentinel value at the end of the variadic arguments.
- A count argument indicating the number of variadic arguments.
[edit] Type safety
Some C implementations, such as GCC, 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. Therefore, care should be taken to ensure correctness in this regard, since undefined behavior results if the types do not match. For example, if passing a null pointer, one should not write simply NULL
but cast to the appropriate pointer type. 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.
[edit] Example
#include <stdio.h> #include <stdarg.h> void printargs (int arg1, ...) /*print all int type args, finishing with -1 */ { va_list s; int g; va_start (s, arg1); for (g = arg1; g != -1; g = va_arg (s, int)) printf ("%d ", g); va_end (s); putchar ('\n'); } int main(void) { printargs (5, 2, 14, 84, 97, 15, 24, 48, -1); printargs (84, 51, -1); printargs (-1); printargs (1, -1); return 0; }
This program yields the output:
5 2 14 84 97 15 24 48 84 51 1
[edit] <varargs.h>
The header <varargs.h>
, which dates from before the standardization of C, provides functionality similar to <stdarg.h>
. This header is not part of ISO C.