196 lines
4.2 KiB
Groff
196 lines
4.2 KiB
Groff
'\"macro stdmacro
|
|
.\"
|
|
.\".AT 3
|
|
.TH stdarg 5
|
|
.SH NAME
|
|
stdarg \- variable argument list
|
|
.SH SYNOPSIS
|
|
.nf
|
|
\f3#include <stdarg.h>\f1
|
|
.sp .6v
|
|
\f3void va_start (va_list ap, \f2ParmN\f3);\f1
|
|
.sp .6v
|
|
\f2type\f1 \f3va_arg (va_list ap, \f2type\f3);\f1
|
|
.sp .6v
|
|
\f3void va_end (va_list ap);\f1
|
|
.fi
|
|
.SH DESCRIPTION
|
|
This set of macros provides a means of writing portable procedures that
|
|
accept variable argument lists.
|
|
Routines having variable argument lists (such as
|
|
.IR printf (3))
|
|
that do not use stdarg are inherently nonportable, since different
|
|
machines use different argument passing conventions.
|
|
The stdarg facility
|
|
is similar to
|
|
.IR varargs (5),
|
|
but is based on the ANSI Standard for C.
|
|
.PP
|
|
A variable argument list contains one or more parameters.
|
|
The rightmost
|
|
parameter plays a special role, and is designated
|
|
.I ParmN
|
|
in this discussion.
|
|
.PP
|
|
.I va_list
|
|
is a type suitable for storing information needed by the macros
|
|
.BR va_start ,
|
|
.BR va_arg ,
|
|
and
|
|
.BR va_end .
|
|
The called function must declare a variable (referred to
|
|
as
|
|
.IR ap )
|
|
of type
|
|
.IR va_list ,
|
|
used to access the argument list.
|
|
.PP
|
|
The
|
|
.B va_start (ap,
|
|
.IR ParmN )
|
|
macro initializes
|
|
.I ap
|
|
for subsequent use by
|
|
.B va_arg
|
|
and
|
|
.BR va_end .
|
|
.B va_start
|
|
must be called before any use of
|
|
.BR va_arg .
|
|
The ANSI C Standard (ANSI X3.159-1989) restricts the type of
|
|
.I parmN
|
|
to one of the types resulting from the
|
|
.IR "default argument promotions" ,
|
|
currently
|
|
.BR int ,
|
|
.BR "unsigned int" ,
|
|
pointer,
|
|
or
|
|
.BR double .
|
|
If
|
|
.B va_start
|
|
is invoked with a
|
|
.I parmN
|
|
which is not one of these types (e.g., if
|
|
.I parmN
|
|
is
|
|
.B short
|
|
or
|
|
.BR char )
|
|
the behavior is undefined.
|
|
.PP
|
|
The
|
|
.B va_arg (ap,
|
|
.IR type )
|
|
macro will return the next argument in the list pointed to by
|
|
.IR ap .
|
|
The first invocation of
|
|
.B va_arg
|
|
returns the value of the argument after that specified by
|
|
.IR ParmN .
|
|
Successive invocations return the values of the remaining arguments in
|
|
succession.
|
|
.I type
|
|
is the type to which the expected argument will be converted
|
|
when passed as an argument, as indicated by the
|
|
.IR "default argument promotions" .
|
|
Thus, arguments that are
|
|
.B char
|
|
or
|
|
.B short
|
|
should be accessed as
|
|
.BR int ;
|
|
.B "unsigned char"
|
|
or
|
|
.B "unsigned short"
|
|
should be accessed as
|
|
.BR "unsigned int" ;
|
|
and
|
|
.B float
|
|
arguments should be accessed as
|
|
.BR double .
|
|
Arguments which are pointers should be accessed
|
|
using their own type.
|
|
Different types can be mixed, but it is up
|
|
to the routine to know what type of argument is
|
|
expected.
|
|
.PP
|
|
.B va_end (ap)
|
|
is used to finish up.
|
|
.PP
|
|
Multiple traversals, each bracketed by
|
|
.B va_start
|
|
\&...
|
|
.B va_end,
|
|
are possible.
|
|
.SH EXAMPLE
|
|
.nf
|
|
#include <stdarg.h>
|
|
#define MAXARGS 31
|
|
void f1(int nptrs, ...)
|
|
{
|
|
va_list ap;
|
|
char *array[MAXARGS];
|
|
int ptr_no = 0;
|
|
if (nptrs > MAXARGS)
|
|
nptrs = MAXARGS;
|
|
va_start(ap, nptrs);
|
|
while (ptr_no < nptrs)
|
|
(array[ptr_no++] = va_arg(ap, char *));
|
|
va_end(ap);
|
|
}
|
|
.fi
|
|
.SH "SEE ALSO"
|
|
varargs(5)
|
|
.SH BUGS
|
|
Due to the procedure calling convention on the MIPS processor,
|
|
floating-point parameters may be inaccessible via
|
|
.I stdarg
|
|
unless they appear
|
|
.I after
|
|
a parameter of non-floating-point type.
|
|
Thus, in the code sequence
|
|
.nf
|
|
extern int foo(float,...);
|
|
foo(1.0,2.0);
|
|
.fi
|
|
the parameter
|
|
.I 2.0
|
|
may be accessed incorrectly.
|
|
If the function expected an intervening
|
|
non-floating-point parameter, such as
|
|
.nf
|
|
extern int foo(float,...);
|
|
foo(1.0,4,2.0);
|
|
.fi
|
|
the second floating-point parameter would be accessible as a
|
|
.IR double .
|
|
No problem is encountered, of course, if the type of the first argument
|
|
is not floating-point.
|
|
.PP
|
|
.I Stdarg
|
|
cannot be used when passing structures as parameters,
|
|
as it is impossible to determine their alignment at runtime.
|
|
.PP
|
|
It is up to the calling routine to determine how many arguments
|
|
there are, since it is not possible to determine this from the
|
|
stack frame.
|
|
For example,
|
|
.I execl
|
|
passes a 0 to signal the end of the list.
|
|
.I Printf
|
|
can tell how many arguments are supposed to be there by the format.
|
|
.PP
|
|
The macros
|
|
.I va_start
|
|
and
|
|
.I va_end
|
|
may be arbitrarily complex;
|
|
for example,
|
|
.I va_start
|
|
might contain an opening brace,
|
|
which is closed by a matching brace in
|
|
.IR va_end .
|
|
Thus, they should only be used where they could
|
|
be placed within a single complex statement.
|