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