varargs
Purpose
Handles a variable-length parameter list.
Syntax
#include <varargs.h>
va_alist type va_arg (argp, type)
va_list argp;
va_dcl
void va_end (argp)
void va_start (argp) va_list argp;
va_list argp;
Description
This set of macros allows you to write portable subrou-
tines that accept a variable number of parameters. Sub-
routines that have variable-length parameter lists (such
as printf), but that do not use varargs, are inherently
nonportable because different systems use different
parameter-passing conventions.
va_alist Is used as the parameter list in the function
header.
va_dcl Is the declaration for va_alist. No semicolon
should follow va_dcl.
va_list Defines the type of the variable used to trav-
erse the list.
va_start Initializes argp to point to the beginning of
the list.
argp Is a variable that the varargs macros use to
keep track of the current location in the
parameter list. Do not modify this variable.
va_arg Returns the next parameter in the list pointed
to by argp. type is the data type that the
parameter is expected to be. Different types
can be mixed, but your subroutine must know
what type of parameter is expected because it
cannot be determined at runtime. The printf
subroutine solves this problem by using its
format parameter to determine the parameter
types expected.
var_end Cleans up at the end.
Your subroutine can traverse, or scan, the parameter list
more than once. Start each traversal with a call to
va_start and end it with var_end.
Note: The calling routine is responsible for specifying
the number of parameters because it is not always pos-
sible to determine this from the stack frame. For
example, execl is passed a NULL pointer to signal the end
of the list. printf determines the number of parameters
from its format parameter.
Specifying char, short, or float as the second parameter
to va_arg. is not portable because parameters seen by the
called subroutine are not char, short, or float. The C
complier converts char and short parameters to int, and
it converts float parameters to double before passing
them to a subroutine.
Example
The following example is a possible implementation of
execl system call:
#include <varargs.h>
#define MAXARGS 100
/*
** execl is called by
** execl(file, arg1, arg2, . . . , (char *) 0);
*/
execl(va_alist)
va_dcl
{
va_list ap;
char *file;
char *args[MAXARGS];
int argno = 0;
va_start(ap);
file = va_arg(ap, char *);
while ((args[argno++] = va_arg(ap, char *)) != (char *) 0)
; /* Empty loop body */
va_end(ap);
return (execv(file, args));
}
Related Information
In this book: "exec: execl, execv, execle, execve,
execlp, execvp," "printf, fprintf, sprintf, NLprintf,
NLfprintf, NLsprintf," and "vprintf, vfprintf, vsprintf."