{{Short description|Header file for C programs}}

{{C Standard Library}} {{lowercase title|title=stdarg.h}} '''{{mono|<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.<ref>{{cite web | url=http://www.opengroup.org/onlinepubs/009695399/basedefs/stdarg.h.html | title=IEEE Std 1003.1 <code>stdarg.h</code> | access-date=2009-07-04}}</ref> It provides facilities for stepping through a list of function arguments of unknown number and type. C++ provides this functionality in the header <code><cstdarg></code>.

The contents of <code><stdarg.h></code> are typically used in variadic functions, though they may be used in other functions (for example, <code>vprintf</code>) 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 <code>printf</code>. Respectively, declarations and definitions are done similarly as such <syntaxhighlight lang="c"> int check(int a, double b, ...);

int check(int a, double b, ...) { // ... } </syntaxhighlight>

According to the standard, varadic functions without any named parameters are not allowed in C17 and earlier, but in C++ and C23<ref name=N2975>{{cite web|url=https://open-std.org/JTC1/SC22/WG14/www/docs/n2975.pdf|title=WG14-N2975 : Relax requirements for variadic parameter lists, v3|date=2022-04-15|last1=Gilding|first1=Alex|last2=Meneide|first2=JeanHeyd}}</ref> 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.<ref>{{cite web |title=Old-style function definitions |url=https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Old_002dStyle-Function-Definitions.html |website=GNU C language |access-date=15 November 2024 |date=2007}}</ref>

==stdarg.h types==

{|class="wikitable" |- ! Name !! Description !! Compatibility |- |<code>[http://en.cppreference.com/w/cpp/utility/variadic/va_list va_list]</code> || type for iterating arguments || C89 |}

==stdarg.h macros==

{|class="wikitable" |- ! Name !! Description !! compatibility |- |<code>[http://en.cppreference.com/w/cpp/utility/variadic/va_start va_start]</code> || Start iterating arguments with a <code>va_list</code> || C89 |- |<code>[http://en.cppreference.com/w/cpp/utility/variadic/va_arg va_arg]</code> || Retrieve an argument || C89 |- |<code>[http://en.cppreference.com/w/cpp/utility/variadic/va_end va_end]</code> || Free a <code>va_list</code> || C89 |- |<code>[http://en.cppreference.com/w/cpp/utility/variadic/va_copy va_copy]</code> || Copy contents of one <code>va_list</code> to another || C99 |}

== Accessing the arguments == According to the standard, to access the unnamed arguments it can be through a variable of type <code>va_list</code> in the variadic function, with macro <code>va_start</code> also provided as the last named parameter of the function. In C23 <!-- and probably C++26 according to https://wg21.link/p2537r1 . Do not add until this paper is accepted for C++26 per WP:CRYSTAL --> the second argument is optional and will not be evaluated.<ref name=N2975/> After this, each invocation of the <code>va_arg</code> macro yields the next argument. The first argument to <code>va_arg</code> is the <code>va_list</code> and the second is the type of the next argument passed to the function. As the last step, the <code>va_end</code> macro must be called on the <code>va_list</code> before the function returns. Note that it is not required to read in all the arguments.

C99 provides an additional macro, <code>va_copy</code>, which can duplicate the state of a <code>va_list</code>. The macro invocation <code>va_copy(va2, va1)</code> copies <code>va1</code> into <code>va2</code>.

There is no defined method for counting or classifying the unnamed arguments passed to the variadic function. The function should simply determine this somehow, the means of which vary. Common conventions include: * Use of a <code>printf</code> or <code>scanf</code>-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.

=== Passing unnamed arguments to other calls === As 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 by <code>va_list</code> inside the receiving function. As a result 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 <code>fprintf()</code>), 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 variadic macros instead of variadic functions. Additionally, most standard library procedures provide <code>v</code>-prefixed alternative versions which accept a ''reference'' to the unnamed argument list (i.e. an initialized <code>va_list</code> variable) instead of the unnamed argument list itself. For example, <code>vfprintf()</code> is an alternate version of <code>fprintf()</code> expecting a <code>va_list</code> instead of the actual unnamed argument list. A user-defined variadic function can therefore initialize a <code>va_list</code> variable using <code>va_start</code> 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 API functions without also providing equivalent functions accepting <code>va_list</code> 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, since undefined behavior results if the types do not match. For example, if the expected type is <code>int*</code>, then a null pointer should be passed as <code>(int*)NULL</code>. Writing just <code>NULL</code> would result in an argument of type either <code>int</code> or <code>void*</code>, neither of which is correct. Another consideration is the default argument promotions applied to the unnamed arguments. A <code>float</code> will automatically be promoted to a <code>double</code>. Likewise, arguments of types narrower than an <code>int</code> will be promoted to <code>int</code> or <code>unsigned int</code>. The function receiving the unnamed arguments must expect the promoted type.{{citation needed|date=November 2024}}

GCC has an attribute that checks the passed arguments: <syntaxhighlight lang="c" inline>gnu::format(style, format_index, first_to_check)</syntaxhighlight>.<ref>{{Cite web|title=gnu::format(3attr - Linux manual page|url=https://www.man7.org/linux/man-pages/man3/gnu::format.3attr.html|publisher=man7|author=Michael Kerrisk|date=16 January 2026|website=man7.org}}</ref> The format attribute specifies that a function takes <code>printf</code>, <code>scanf</code>, <code>strftime</code> or <code>strfmon</code> style arguments which should be type-checked against a format string. For example, the declaration:

<syntaxhighlight lang="c"> gnu::format(printf, 2, 3) extern int my_printf(void* obj, const char* fmt, ...); </syntaxhighlight>

causes the compiler to check the arguments in calls to <code>my_printf</code> for consistency with the <code>printf</code> style format string argument <code>my_format</code>.<ref>{{cite web | title = 5.27 Extensions to the C Language Family - Declaring Attributes of Functions | url=https://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Function-Attributes.html#Function-Attributes | access-date = 2009-01-03 }}</ref>

==Example==

<syntaxhighlight lang=c> #include <stdio.h> #include <stdarg.h>

// Get sum of variables int sum(int count, ...) { va_list ap; int total = 0; va_start(ap, count); for (int i = 0; i < count; i++) { total += va_arg(ap, int); } va_end(ap); return total; }

int main(void) { printf("%i", sum(2, 1, 3)); return 0; } </syntaxhighlight>

This program should get the following output:

<pre> 4 </pre>

=={{mono|<varargs.h>}}== Outdated versions of POSIX defined the legacy header <code><varargs.h></code>, which dates from before the standardization of C and provides functionality similar to <code><stdarg.h></code>. 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 <code><stdarg.h></code>, 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 {{code|printargs}} example, one would instead write:

<syntaxhighlight lang="c"> #include <stdio.h> #include <varargs.h>

/** * 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; } </syntaxhighlight>

and is called the same way.

<code>varargs.h</code> requires old-style function definitions because of the way the implementation works.<ref>{{cite web | url=http://www.opengroup.org/onlinepubs/007908799/xsh/varargs.h.html | title=Single UNIX Specification <code>varargs.h</code> | access-date=2007-08-01}}</ref> Conversely, it is not possible to mix old-style function definitions with <code>stdarg.h</code>.

==References== {{Reflist}}

{{CProLang|state=expanded}}

Category:Articles with example C code Category:C standard library headers