xref: /openbsd/share/man/man3/va_start.3 (revision 4cfece93)
1.\"	$OpenBSD: va_start.3,v 1.1 2019/08/30 18:33:17 deraadt Exp $
2.\"	$NetBSD: stdarg.3,v 1.15 2002/08/18 08:57:07 yamt Exp $
3.\"
4.\" Copyright (c) 1990, 1991, 1993
5.\"	The Regents of the University of California.  All rights reserved.
6.\"
7.\" This code is derived from software contributed to Berkeley by
8.\" the American National Standards Committee X3, on Information
9.\" Processing Systems.
10.\"
11.\" Redistribution and use in source and binary forms, with or without
12.\" modification, are permitted provided that the following conditions
13.\" are met:
14.\" 1. Redistributions of source code must retain the above copyright
15.\"    notice, this list of conditions and the following disclaimer.
16.\" 2. Redistributions in binary form must reproduce the above copyright
17.\"    notice, this list of conditions and the following disclaimer in the
18.\"    documentation and/or other materials provided with the distribution.
19.\" 3. Neither the name of the University nor the names of its contributors
20.\"    may be used to endorse or promote products derived from this software
21.\"    without specific prior written permission.
22.\"
23.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33.\" SUCH DAMAGE.
34.\"
35.\"	@(#)stdarg.3	8.1 (Berkeley) 6/5/93
36.\"
37.Dd $Mdocdate: August 30 2019 $
38.Dt VA_START 3
39.Os
40.Sh NAME
41.Nm va_start ,
42.Nm va_arg ,
43.Nm va_copy ,
44.Nm va_end
45.Nd variable argument lists
46.Sh SYNOPSIS
47.In stdarg.h
48.Ft void
49.Fn va_start "va_list ap" last
50.Ft type
51.Fn va_arg "va_list ap" type
52.Ft void
53.Fn va_copy "va_list dst" "va_list src"
54.Ft void
55.Fn va_end "va_list ap"
56.Sh DESCRIPTION
57A function may be called with a varying number of arguments of varying
58types.
59The include file
60.In stdarg.h
61declares a type
62.Vt va_list
63and defines three macros for stepping
64through a list of arguments whose number and types are not known to
65the called function.
66.Pp
67The called function must declare an object of type
68.Vt va_list
69which is used by the macros
70.Fn va_start ,
71.Fn va_arg ,
72.Fn va_end ,
73and, optionally,
74.Fn va_copy .
75.Pp
76The
77.Fn va_start
78macro initializes
79.Fa ap
80for subsequent use by
81.Fn va_arg ,
82.Fn va_copy
83and
84.Fn va_end ,
85and must be called first.
86.Pp
87The parameter
88.Fa last
89is the name of the last parameter before the variable argument list,
90i.e., the last parameter of which the calling function knows the type.
91.Pp
92Because the address of this parameter is used in the
93.Fn va_start
94macro, it should not be declared as a register variable, nor as a
95function, nor an array type.
96.Pp
97The
98.Fn va_arg
99macro expands to an expression that has the type and value of the next
100argument in the call.
101The parameter
102.Fa ap
103is the
104.Va va_list ap
105initialized by
106.Fn va_start .
107Each call to
108.Fn va_arg
109modifies
110.Fa ap
111so that the next call returns the next argument.
112The parameter
113.Fa type
114is a type name specified so that the type of a pointer to an
115object that has the specified type can be obtained simply by
116adding a
117.Ql *
118to
119.Fa type .
120.Pp
121If there is no next argument, or if
122.Fa type
123is not compatible with the type of the actual next argument
124(as promoted according to the default argument promotions, see below),
125random errors will occur.
126.Pp
127If the type in question is one that would normally be promoted, the
128promoted type should be used as the argument to
129.Fn va_arg .
130The following describes which types should be promoted (and to what):
131.Bl -dash -compact
132.It
133.Vt short
134is promoted to
135.Vt int
136.It
137.Vt float
138is promoted to
139.Vt double
140.It
141.Vt char
142is promoted to
143.Vt int
144.El
145.Pp
146The same rules apply to unsigned versions of the above types, as well
147as their bit-type equivalents (e.g.\&
148.Vt int8_t
149and
150.Vt int16_t ) .
151.Pp
152The
153.Fn va_copy
154macro makes
155.Fa dst
156a copy of
157.Fa src
158as if the
159.Fn va_start
160macro had been applied to it followed by the same sequence of uses of the
161.Fn va_arg
162macro as had previously been used to reach the present state of
163.Fa src .
164.Pp
165The
166.Fn va_end
167macro handles a normal return from the function whose variable argument
168list was initialized by
169.Fn va_start
170or
171.Fn va_copy .
172.Sh RETURN VALUES
173The first use of the
174.Fn va_arg
175macro after that of the
176.Fn va_start
177macro returns the argument after
178.Fa last .
179Successive invocations return the values of the remaining
180arguments.
181.Pp
182The
183.Fn va_start ,
184.Fn va_copy
185and
186.Fn va_end
187macros return no value.
188.Sh EXAMPLES
189The function
190.Fn foo
191takes a string of format characters and prints out the argument
192associated with each format character based on the type.
193.Bd -literal -offset indent
194void
195foo(char *fmt, ...)
196{
197	va_list ap;
198	int d, c;
199	char *s;
200	double f;
201
202	va_start(ap, fmt);
203	while (*fmt)
204		switch (*fmt++) {
205		case 's':			/* string */
206			s = va_arg(ap, char *);
207			printf("string %s\en", s);
208			break;
209		case 'd':			/* int */
210			d = va_arg(ap, int);
211			printf("int %d\en", d);
212			break;
213		case 'c':			/* char */
214			c = va_arg(ap, int);	/* promoted */
215			printf("char %c\en", c);
216			break;
217		case 'f':			/* float */
218			f = va_arg(ap, double); /* promoted */
219			printf("float %f\en", f);
220		}
221	va_end(ap);
222}
223.Ed
224.Sh STANDARDS
225These macros are
226.Em not
227compatible with the historic macros they replace.
228A backward compatible version can be found in the include
229file
230.In varargs.h .
231.Pp
232The
233.Fn va_start ,
234.Fn va_arg
235and
236.Fn va_end
237macros conform to
238.St -isoC-99 .
239.Sh HISTORY
240The
241.Fn va_start ,
242.Fn va_arg
243and
244.Fn va_end
245macros were introduced in
246.St -ansiC .
247The
248.Fn va_copy
249macro was introduced in
250.St -isoC-99 .
251.Sh BUGS
252Unlike the
253.Em varargs
254macros, the
255.Nm stdarg
256macros do not permit programmers to
257code a function with no fixed arguments.
258This problem generates work mainly when converting
259.Em varargs
260code to
261.Nm stdarg
262code,
263but it also creates difficulties for variadic functions that
264wish to pass all of their arguments on to a function
265that takes an argument of type
266.Vt va_list ,
267such as
268.Xr vfprintf 3 .
269