1
0
Files
irix-657m-src/eoe/man/man5/stdarg.5
2022-09-29 17:59:04 +03:00

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.