Stdarg.h
≈ 4 min read
Names in other languages
No names in other languages are held for this entry yet.
Article bodies are English and are not machine-translated. A name in another language is not a translation of the article.
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. C++ provides this functionality in the header . The contents of are typically used in variadic functions, though they may be used in other functions (for example, vprintf ) called by variadic functions.
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. C++ provides this functionality in the header . The contents of are typically used in variadic functions, though they may be used in other functions (for example, vprintf ) called by variadic functions. ==Creating variadic functions== Variadic functions are functions which may take a variable number of arguments and are declared with an ellipsis in place of the last parameter. An example of such a function is printf . Respectively, declarations and definitions are done similarly as such int check(int a, double b, ...); int check(int a, double b, ...) { // ... } According to the standard, varadic functions without any named parameters are not allowed in C17 and earlier, but in C++ and C23 such a declaration is permitted. In C, a comma must precede the ellipsis if a named parameter is specified, while in C++ it was optional until C++26 when this was deprecated. Some K&R C style function declarations do not use ellipses. ==stdarg.h types== ==stdarg.h macros== ==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, since undefined behavior results if the types do not match. For example, if the expected type is int* , 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 attribute that checks the passed arguments: gnu::format(style, format_index, first_to_check) . The format attribute specifies that a function takes printf , scanf , strftime or strfmon style arguments which should be type-checked against a format string. For example, the declaration: gnu::format(printf, 2, 3) extern int my_printf(void* obj, const char* fmt, ...); causes the compiler to check the arguments in calls to my_printf for consistency with the printf style format string argument my_format . ==Example== include include // Get sum of variables int sum(int count, ...) { va_list ap; int total = 0; va_start(ap, count); for (int i = 0; i This program should get the following output: 4 == == Outdated versions of POSIX defined the legacy header , which dates from before the standardization of C and provides functionality similar to . 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 , 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: include include /** * This is K&R C (pre-C89). * There is no "void" type; use an implicit int return. */ printargs(arg1, va_alist) va_dcl /* no semicolon here! */ { va_list ap; int i = 0; va_start(ap); /* only the va_list is given! */ for (i = arg1; i >= 0; i = va_arg(ap, int)) { printf("%d ", i); } va_end(ap); putchar('\n'); return; } and is called the same way. 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==
Text derived from https://en.wikipedia.org/w/index.php?oldid=1359587910 under CC BY-SA 4.0; modifications have been made.