Initial revision
authorsandra <sandra>
Wed, 31 Jul 1991 15:13:56 +0000 (15:13 +0000)
committersandra <sandra>
Wed, 31 Jul 1991 15:13:56 +0000 (15:13 +0000)
manual/=stdarg.texi [new file with mode: 0644]

diff --git a/manual/=stdarg.texi b/manual/=stdarg.texi
new file mode 100644 (file)
index 0000000..163a64c
--- /dev/null
@@ -0,0 +1,275 @@
+@node Variable Argument Facilities
+@chapter Variable Argument Facilities
+@pindex <stdarg.h>
+@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 argument functions}, or
+simply @dfn{variadic functions}.)  However, the kernel language provides
+no mechanism for actually accessing non-required arguments; instead,
+this mechanism is defined as a set of macros in the C library as a
+standard language extension.  You must include the header file
+@file{<stdarg.h>} to make use of these macros.
+
+@menu
+* Why Variable Arguments are Used::    
+* 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
+@section Why Variable Arguments are Used
+
+Most C functions take a fixed number of arguments.  When you declare or
+define a function, you also supply a specific data type for each 
+argument.  Calls to the function with the wrong number or type of 
+arguments don't work.
+
+On the other hand, sometimes a function performs an operation that makes
+sense no matter how many arguments it is called with.  
+
+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
+@section How Variable Arguments are Used
+
+This section describes how functions that take variable arguments are
+defined and called, and how the values of the non-required arguments are
+accessed.
+
+@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
+@subsection Syntax for Variable Arguments
+
+The syntax in the language kernel requires that a function that accepts
+a variable number of arguments have at least one required argument with
+a known type.  In the function definition or prototype declaration, the
+fact that a function can accept additional arguments of unspecified type
+is indicated with a trailing argument list of @samp{@dots{}}.  For
+example,
+
+@example
+int func (const char *a, int b, @dots{})
+@dots{}
+@end example
+
+@noindent
+begins 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 with a @code{register} storage
+class in the actual function definition.  Furthermore, this argument
+must not be of a function or array type, or of a type that is not
+compatible with the type that results after application of the default
+argument promotions.
+
+@strong{Compatibility Note:} Many older C dialects provide a similar,
+but incompatible, mechanism for defining variadic arguments functions.
+In particular, the @samp{@dots{}} syntax is a new feature of ANSI C.
+
+
+@node Receiving the Argument Values
+@subsection Receiving the Argument Values
+
+Inside the definition of a variadic arguments function, the optional
+arguments can be accessed using a set of macros.  The process consists
+of three steps:
+
+@enumerate
+@item
+A variable of type @code{va_list} is initialized using @code{va_start}.
+
+@item
+The optional arguments are accessed by successive calls to @code{va_arg}.
+
+@item
+A call to @code{va_end} performs any internal cleanup operations that are
+necessary.
+@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 more arguments than were actually supplied.
+
+
+@node How Many Arguments
+@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 decide when to
+stop fetching more optional arguments.  It is up to you to define an
+appropriate protocol for each function, and write all callers
+appropriately.
+
+If all of the optional arguments are expected to be of the same type,
+making one of the required arguments be an explicit argument count is
+the most obvious technique for specifying how many optional arguments
+are supplied.
+
+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 be used to indicate the end of the argument list, provided that
+a null pointer isn't otherwise meaningful to the function.
+
+
+@node Calling Variadic Functions
+@subsection Calling Variadic Functions
+
+Functions that are @emph{defined} to be variadic 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}, or @code{int} bit fields, 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
+@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>}.
+
+@deftp {Data Type} va_list
+The type @code{va_list} is used to represent a list of an
+unknown number of arguments of unknown types.@refill
+@end deftp
+
+@deftypefn {Macro} void va_start (va_list @var{ap}, @var{last_required})
+This macro initializes the variable @var{ap} to hold the list of
+optional arguments supplied to the function; @var{last_required} must be
+the last required argument parameter to the function.  Initially, @var{ap}
+``points to'' the first optional argument.
+@end deftypefn
+
+@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.
+The type of the value returned by @code{va_arg} is the @var{type}
+specified in the call.  You must be careful that this @var{type}
+is the same as the type of the actual argument value after the default
+argument promotions are performed; if they aren't compatible, bad
+things will happen.
+@end deftypefn
+
+@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} will not work.  You must invoke
+@code{va_end} before returning from the function in which @code{va_start}
+was invoked with the same @var{ap} argument.@refill
+@end deftypefn
+
+
+@node Example of Variable Arguments
+@section Example of Variable Arguments
+
+Here is a full example of a function using these macros.  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;
+@}
+
+@dots{}
+
+  /* @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