1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
|
@node Variable Argument Facilities, Memory Allocation, Common Definitions, Top
@chapter Variable Argument Facilities
@cindex variadic argument functions
@cindex variadic functions
@cindex variable number of arguments
@cindex optional arguments
ANSI C defines a syntax as part of the kernel language for specifying
functions that take a variable number or type of arguments. (Such
functions are also referred to as @dfn{variadic functions}.) However,
the kernel language provides no mechanism for actually accessing
non-required arguments; instead, you use the variable arguments macros
defined in @file{stdarg.h}.
@pindex stdarg.h
@menu
* Why Variable Arguments are Used:: Using variable arguments can
save you time and effort.
* How Variable Arguments are Used:: An overview of the facilities for
receiving variable arguments.
* Variable Arguments Interface:: Detailed specification of the
library facilities.
* Example of Variable Arguments:: A complete example.
@end menu
@node Why Variable Arguments are Used, How Variable Arguments are Used, , Variable Argument Facilities
@section Why Variable Arguments are Used
Most C functions take a fixed number of arguments. When you define a
function, you also supply a specific data type for each argument.
Every call to the function should supply the same number and type of
arguments as specified in the function definition.
On the other hand, sometimes a function performs an operation that can
meaningfully accept an unlimited number of arguments.
For example, consider a function that joins its arguments into a linked
list. It makes sense to connect any number of arguments together into a
list of arbitrary length. Without facilities for variable arguments,
you would have to define a separate function for each possible number of
arguments you might want to link together. This is an example of a
situation where some kind of mapping or iteration is performed over an
arbitrary number of arguments of the same type.
Another kind of application where variable arguments can be useful is
for functions where values for some arguments can simply be omitted in
some calls, either because they are not used at all or because the
function can determine appropriate defaults for them if they're missing.
The library function @code{printf} (@pxref{Formatted Output}) is an
example of still another class of function where variable arguments are
useful. This function prints its arguments (which can vary in type as
well as number) under the control of a format template string.
@node How Variable Arguments are Used, Variable Arguments Interface, Why Variable Arguments are Used, Variable Argument Facilities
@section How Variable Arguments are Used
This section describes how you can define and call functions that take
variable arguments, and how to access the values of the non-required
arguments.
@menu
* Syntax for Variable Arguments:: How to make a prototype for a
function with variable arguments.
* Receiving the Argument Values:: Steps you must follow to access the
optional argument values.
* How Many Arguments:: How to decide whether there are more
arguments.
* Calling Variadic Functions:: Things you need to know about calling
variable arguments functions.
@end menu
@node Syntax for Variable Arguments, Receiving the Argument Values, , How Variable Arguments are Used
@subsection Syntax for Variable Arguments
A function that accepts a variable number of arguments must have at
least one required argument with a specified type. In the function
definition or prototype declaration, you indicate the fact that a
function can accept additional arguments of unspecified type by putting
@samp{@dots{}} at the end of the arguments. For example,
@example
int
func (const char *a, int b, @dots{})
@{
@dots{}
@}
@end example
@noindent
outlines a definition of a function @code{func} which returns an
@code{int} and takes at least two arguments, the first two being a
@code{const char *} and an @code{int}.@refill
An obscure restriction placed by the ANSI C standard is that the last
required argument must not be declared @code{register} in the function
definition. Furthermore, this argument must not be of a function or
array type, and may not be, for example, a @code{char} or @code{short
int} (whether signed or not) or a @code{float}.
@strong{Compatibility Note:} Many older C dialects provide a similar,
but incompatible, mechanism for defining functions with variable numbers
of arguments. In particular, the @samp{@dots{}} syntax is a new feature
of ANSI C.
@node Receiving the Argument Values, How Many Arguments, Syntax for Variable Arguments, How Variable Arguments are Used
@subsection Receiving the Argument Values
Inside the definition of a variadic function, to access the optional
arguments with the following three step process:
@enumerate
@item
You initialize an argument pointer variable of type @code{va_list} using
@code{va_start}.
@item
You access the optional arguments by successive calls to @code{va_arg}.
@item
You call @code{va_end} to indicate that you are finished accessing the
arguments.
@end enumerate
Steps 1 and 3 must be performed in the function that is defined to
accept variable arguments. However, you can pass the @code{va_list}
variable as an argument to another function and perform all or part of
step 2 there. After doing this, the value of the @code{va_list}
variable in the calling function becomes undefined for further calls to
@code{va_arg}; you should just pass it to @code{va_end}.
You can perform the entire sequence of the three steps multiple times
within a single function invocation. And, if the function doesn't want
to look at its optional arguments at all, it doesn't have to do any of
these steps. It is also perfectly all right for a function to access
fewer arguments than were supplied in the call, but you will get garbage
values if you try to access too many arguments.
@node How Many Arguments, Calling Variadic Functions, Receiving the Argument Values, How Variable Arguments are Used
@subsection How Many Arguments Were Supplied
There is no general way for a function to determine the number and type
of the actual values that were passed as optional arguments. Typically,
the value of one of the required arguments is used to tell the function
this information. It is up to you to define an appropriate calling
convention for each function, and write all calls accordingly.
One calling convention is to make one of the required arguments be an
explicit argument count. This convention is usable if all of the
optional arguments are of the same type.
A required argument can be used as a pattern to specify both the number
and types of the optional arguments. The format template string
argument to @code{printf} is one example of this.
A similar technique that is sometimes used is to have one of the
required arguments be a bit mask, with a bit for each possible optional
argument that might be supplied. The bits are tested in a predefined
sequence; if the bit is set, the value of the next argument is
retrieved, and otherwise a default value is used.
Another technique that is sometimes used is to pass an ``end marker''
value as the last optional argument. For example, for a function that
manipulates an arbitrary number of pointer arguments, a null pointer
might indicate the end of the argument list, provided that a null
pointer isn't otherwise meaningful to the function.
@node Calling Variadic Functions, , How Many Arguments, How Variable Arguments are Used
@subsection Calling Variadic Functions
Functions that are @emph{defined} to be variadic must also be
@emph{declared} to be variadic using a function prototype in the scope
of all calls to it. This is because C compilers might use a different
internal function call protocol for variadic functions than for
functions that take a fixed number and type of arguments. If the
compiler can't determine in advance that the function being called is
variadic, it may end up trying to call it incorrectly and your program
won't work.
@cindex function prototypes
@cindex prototypes for variadic functions
@cindex variadic functions need prototypes
Since the prototype doesn't specify types for optional arguments, in a
call to a variadic function the @dfn{default argument promotions} are
performed on the optional argument values. This means the objects of
type @code{char} or @code{short int} (whether signed or not) are
promoted to either @code{int} or @code{unsigned int}, as appropriate;
and that objects of type @code{float} are promoted to type
@code{double}. So, if the caller passes a @code{char} as an optional
argument, it is promoted to a @code{int}, and the function should get it
with @code{va_arg (@var{ap}, int)}.
Promotions of the required arguments are determined by the function
prototype in the usual way (as if by assignment to the types of the
corresponding formal parameters).
@cindex default argument promotions
@cindex argument promotion
@node Variable Arguments Interface, Example of Variable Arguments, How Variable Arguments are Used, Variable Argument Facilities
@section Variable Arguments Interface
Here are descriptions of the macros used to retrieve variable arguments.
These macros are defined in the header file @file{stdarg.h}.
@pindex stdarg.h
@comment stdarg.h
@comment ANSI
@deftp {Data Type} va_list
The type @code{va_list} is used for argument pointer variables.
@end deftp
@comment stdarg.h
@comment ANSI
@deftypefn {Macro} void va_start (va_list @var{ap}, @var{last_required})
This macro initialized the argument pointer variable @var{ap} to point
to the first of the optional arguments of the current function;
@var{last_required} must be the last required argument to the function.
@end deftypefn
@comment stdarg.h
@comment ANSI
@deftypefn {Macro} @var{type} va_arg (va_list @var{ap}, @var{type})
The @code{va_arg} macro returns the value of the next optional argument,
and changes the internal state of @var{ap} to move past this argument.
Thus, successive uses of @code{va_arg} return successive optional
arguments.
The type of the value returned by @code{va_arg} is the @var{type}
specified in the call.
The @var{type} must match the type of the actual argument, and must not
be @code{char} or @code{short int} or @code{float}. (Remember that the
default argument promotions apply to optional arguments.)
@end deftypefn
@comment stdarg.h
@comment ANSI
@deftypefn {Macro} void va_end (va_list @var{ap})
This ends the use of @var{ap}. After a @code{va_end} call, further
@code{va_arg} calls with the same @var{ap} may not work. You should invoke
@code{va_end} before returning from the function in which @code{va_start}
was invoked with the same @var{ap} argument.
In the GNU C library, @code{va_end} does nothing, and you need not ever
use it except for reasons of portability.
@refill
@end deftypefn
@node Example of Variable Arguments, , Variable Arguments Interface, Variable Argument Facilities
@section Example of Variable Arguments
Here is a complete sample function that accepts variable numbers of
arguments. The first argument to the function is the count of remaining
arguments, which are added up and the result returned. (This is
obviously a rather pointless function, but it serves to illustrate the
way the variable arguments facility is commonly used.)
@comment Yes, this example has been tested.
@example
#include <stdarg.h>
int
add_em_up (int count, @dots{})
@{
va_list ap;
int i, sum;
va_start (ap, count); /* @r{Initialize the argument list.} */
sum = 0;
for (i = 0; i < count; i++)
sum = sum + va_arg (ap, int); /* @r{Get the next argument value.} */
va_end (ap); /* @r{Clean up.} */
return sum;
@}
void main (void)
@{
/* @r{This call prints 16.} */
printf ("%d\n", add_em_up (3, 5, 5, 6));
/* @r{This call prints 55.} */
printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
@}
@end example
|