diff options
Diffstat (limited to 'manual/=stdarg.texi')
-rw-r--r-- | manual/=stdarg.texi | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/manual/=stdarg.texi b/manual/=stdarg.texi new file mode 100644 index 0000000000..384c992f13 --- /dev/null +++ b/manual/=stdarg.texi @@ -0,0 +1,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 |