mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			291 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			291 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
@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
 |