| .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
| .\" All rights reserved. |
| .\" |
| .\" This code is derived from software contributed to Berkeley by |
| .\" the American National Standards Committee X3, on Information |
| .\" Processing Systems. |
| .\" |
| .\" %%%LICENSE_START(BSD_4_CLAUSE_UCB) |
| .\" Redistribution and use in source and binary forms, with or without |
| .\" modification, are permitted provided that the following conditions |
| .\" are met: |
| .\" 1. Redistributions of source code must retain the above copyright |
| .\" notice, this list of conditions and the following disclaimer. |
| .\" 2. Redistributions in binary form must reproduce the above copyright |
| .\" notice, this list of conditions and the following disclaimer in the |
| .\" documentation and/or other materials provided with the distribution. |
| .\" 3. All advertising materials mentioning features or use of this software |
| .\" must display the following acknowledgement: |
| .\" This product includes software developed by the University of |
| .\" California, Berkeley and its contributors. |
| .\" 4. Neither the name of the University nor the names of its contributors |
| .\" may be used to endorse or promote products derived from this software |
| .\" without specific prior written permission. |
| .\" |
| .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| .\" SUCH DAMAGE. |
| .\" %%%LICENSE_END |
| .\" |
| .\" @(#)stdarg.3 6.8 (Berkeley) 6/29/91 |
| .\" |
| .\" Converted for Linux, Mon Nov 29 15:11:11 1993, faith@cs.unc.edu |
| .\" Additions, 2001-10-14, aeb |
| .\" |
| .TH STDARG 3 2021-03-22 "" "Linux Programmer's Manual" |
| .SH NAME |
| stdarg, va_start, va_arg, va_end, va_copy \- variable argument lists |
| .SH SYNOPSIS |
| .nf |
| .B #include <stdarg.h> |
| .PP |
| .BI "void va_start(va_list " ap ", " last ); |
| .IB type " va_arg(va_list " ap ", " type ); |
| .BI "void va_end(va_list " ap ); |
| .BI "void va_copy(va_list " dest ", va_list " src ); |
| .fi |
| .SH DESCRIPTION |
| A function may be called with a varying number of arguments of varying |
| types. |
| The include file |
| .I <stdarg.h> |
| declares a type |
| .I va_list |
| and defines three macros for stepping through a list of arguments whose |
| number and types are not known to the called function. |
| .PP |
| The called function must declare an object of type |
| .I va_list |
| which is used by the macros |
| .BR va_start (), |
| .BR va_arg (), |
| and |
| .BR va_end (). |
| .SS va_start() |
| The |
| .BR va_start () |
| macro initializes |
| .I ap |
| for subsequent use by |
| .BR va_arg () |
| and |
| .BR va_end (), |
| and must be called first. |
| .PP |
| The argument |
| .I last |
| is the name of the last argument before the variable argument list, that is, |
| the last argument of which the calling function knows the type. |
| .PP |
| Because the address of this argument may be used in the |
| .BR va_start () |
| macro, it should not be declared as a register variable, |
| or as a function or an array type. |
| .SS va_arg() |
| The |
| .BR va_arg () |
| macro expands to an expression that has the type and value of the next |
| argument in the call. |
| The argument |
| .I ap |
| is the |
| .I va_list |
| .I ap |
| initialized by |
| .BR va_start (). |
| Each call to |
| .BR va_arg () |
| modifies |
| .I ap |
| so that the next call returns the next argument. |
| The argument |
| .I type |
| is a type name specified so that the type of a pointer to an object that |
| has the specified type can be obtained simply by adding a * to |
| .IR type . |
| .PP |
| The first use of the |
| .BR va_arg () |
| macro after that of the |
| .BR va_start () |
| macro returns the argument after |
| .IR last . |
| Successive invocations return the values of the remaining arguments. |
| .PP |
| If there is no next argument, or if |
| .I type |
| is not compatible with the type of the actual next argument (as promoted |
| according to the default argument promotions), random errors will occur. |
| .PP |
| If |
| .I ap |
| is passed to a function that uses |
| .BI va_arg( ap , type ), |
| then the value of |
| .I ap |
| is undefined after the return of that function. |
| .SS va_end() |
| Each invocation of |
| .BR va_start () |
| must be matched by a corresponding invocation of |
| .BR va_end () |
| in the same function. |
| After the call |
| .BI va_end( ap ) |
| the variable |
| .I ap |
| is undefined. |
| Multiple traversals of the list, each |
| bracketed by |
| .BR va_start () |
| and |
| .BR va_end () |
| are possible. |
| .BR va_end () |
| may be a macro or a function. |
| .SS va_copy() |
| The |
| .BR va_copy () |
| macro copies the (previously initialized) variable argument list |
| .I src |
| to |
| .IR dest . |
| The behavior is as if |
| .BR va_start () |
| were applied to |
| .IR dest |
| with the same |
| .I last |
| argument, followed by the same number of |
| .BR va_arg () |
| invocations that was used to reach the current state of |
| .IR src . |
| .PP |
| .\" Proposal from clive@demon.net, 1997-02-28 |
| An obvious implementation would have a |
| .I va_list |
| be a pointer to the stack frame of the variadic function. |
| In such a setup (by far the most common) there seems |
| nothing against an assignment |
| .PP |
| .in +4n |
| .EX |
| va_list aq = ap; |
| .EE |
| .in |
| .PP |
| Unfortunately, there are also systems that make it an |
| array of pointers (of length 1), and there one needs |
| .PP |
| .in +4n |
| .EX |
| va_list aq; |
| *aq = *ap; |
| .EE |
| .in |
| .PP |
| Finally, on systems where arguments are passed in registers, |
| it may be necessary for |
| .BR va_start () |
| to allocate memory, store the arguments there, and also |
| an indication of which argument is next, so that |
| .BR va_arg () |
| can step through the list. |
| Now |
| .BR va_end () |
| can free the allocated memory again. |
| To accommodate this situation, C99 adds a macro |
| .BR va_copy (), |
| so that the above assignment can be replaced by |
| .PP |
| .in +4n |
| .EX |
| va_list aq; |
| va_copy(aq, ap); |
| \&... |
| va_end(aq); |
| .EE |
| .in |
| .PP |
| Each invocation of |
| .BR va_copy () |
| must be matched by a corresponding invocation of |
| .BR va_end () |
| in the same function. |
| Some systems that do not supply |
| .BR va_copy () |
| have |
| .B __va_copy |
| instead, since that was the name used in the draft proposal. |
| .SH ATTRIBUTES |
| For an explanation of the terms used in this section, see |
| .BR attributes (7). |
| .ad l |
| .nh |
| .TS |
| allbox; |
| lbx lb lb |
| l l l. |
| Interface Attribute Value |
| T{ |
| .BR va_start (), |
| .BR va_end (), |
| .BR va_copy () |
| T} Thread safety MT-Safe |
| T{ |
| .BR va_arg () |
| T} Thread safety MT-Safe race:ap |
| .TE |
| .hy |
| .ad |
| .sp 1 |
| .SH CONFORMING TO |
| The |
| .BR va_start (), |
| .BR va_arg (), |
| and |
| .BR va_end () |
| macros conform to C89. |
| C99 defines the |
| .BR va_copy () |
| macro. |
| .SH BUGS |
| Unlike the historical |
| .B varargs |
| macros, the |
| .B stdarg |
| macros do not permit programmers to code a function with no fixed |
| arguments. |
| This problem generates work mainly when converting |
| .B varargs |
| code to |
| .B stdarg |
| code, but it also creates difficulties for variadic functions that wish to |
| pass all of their arguments on to a function that takes a |
| .I va_list |
| argument, such as |
| .BR vfprintf (3). |
| .SH EXAMPLES |
| The function |
| .I foo |
| takes a string of format characters and prints out the argument associated |
| with each format character based on the type. |
| .PP |
| .EX |
| #include <stdio.h> |
| #include <stdarg.h> |
| |
| void |
| foo(char *fmt, ...) /* \(aq...\(aq is C syntax for a variadic function */ |
| |
| { |
| va_list ap; |
| int d; |
| char c; |
| char *s; |
| |
| va_start(ap, fmt); |
| while (*fmt) |
| switch (*fmt++) { |
| case \(aqs\(aq: /* string */ |
| s = va_arg(ap, char *); |
| printf("string %s\en", s); |
| break; |
| case \(aqd\(aq: /* int */ |
| d = va_arg(ap, int); |
| printf("int %d\en", d); |
| break; |
| case \(aqc\(aq: /* char */ |
| /* need a cast here since va_arg only |
| takes fully promoted types */ |
| c = (char) va_arg(ap, int); |
| printf("char %c\en", c); |
| break; |
| } |
| va_end(ap); |
| } |
| .EE |
| .SH SEE ALSO |
| .BR vprintf (3), |
| .BR vscanf (3), |
| .BR vsyslog (3) |