mirror of https://github.com/mkerrisk/man-pages
310 lines
7.7 KiB
Groff
310 lines
7.7 KiB
Groff
.\" Copyright (c) 1990, 1991 The Regents of the University of California.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" This code is derived from software contributed to Berkeley by
|
|
.\" the American National Standards Committee X3, on Information
|
|
.\" Processing Systems.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. All advertising materials mentioning features or use of this software
|
|
.\" must display the following acknowledgement:
|
|
.\" This product includes software developed by the University of
|
|
.\" California, Berkeley and its contributors.
|
|
.\" 4. Neither the name of the University nor the names of its contributors
|
|
.\" may be used to endorse or promote products derived from this software
|
|
.\" without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
.\" SUCH DAMAGE.
|
|
.\"
|
|
.\" @(#)stdarg.3 6.8 (Berkeley) 6/29/91
|
|
.\"
|
|
.\" Converted for Linux, Mon Nov 29 15:11:11 1993, faith@cs.unc.edu
|
|
.\" Additions, 2001-10-14, aeb
|
|
.\"
|
|
.TH STDARG 3 2001-10-14 "" "Linux Programmer's Manual"
|
|
.SH NAME
|
|
stdarg, va_start, va_arg, va_end, va_copy \- variable argument lists
|
|
.SH SYNOPSIS
|
|
.B #include <stdarg.h>
|
|
.sp
|
|
.BI "void va_start(va_list " ap ", " last );
|
|
.br
|
|
.IB type " va_arg(va_list " ap ", " type );
|
|
.br
|
|
.BI "void va_end(va_list " ap );
|
|
.br
|
|
.BI "void va_copy(va_list " dest ", va_list " src );
|
|
.SH DESCRIPTION
|
|
A function may be called with a varying number of arguments of varying
|
|
types.
|
|
The include file
|
|
.I <stdarg.h>
|
|
declares a type
|
|
.I va_list
|
|
and defines three macros for stepping through a list of arguments whose
|
|
number and types are not known to the called function.
|
|
.PP
|
|
The called function must declare an object of type
|
|
.I va_list
|
|
which is used by the macros
|
|
.BR va_start (),
|
|
.BR va_arg (),
|
|
and
|
|
.BR va_end ().
|
|
.SS va_start()
|
|
The
|
|
.BR va_start ()
|
|
macro initializes
|
|
.I ap
|
|
for subsequent use by
|
|
.BR va_arg ()
|
|
and
|
|
.BR va_end (),
|
|
and must be called first.
|
|
.PP
|
|
The parameter
|
|
.I last
|
|
is the name of the last parameter before the variable argument list, that is,
|
|
the last parameter of which the calling function knows the type.
|
|
.PP
|
|
Because the address of this parameter may be used in the
|
|
.BR va_start ()
|
|
macro, it should not be declared as a register variable,
|
|
or as a function or an array type.
|
|
.SS va_arg()
|
|
The
|
|
.BR va_arg ()
|
|
macro expands to an expression that has the type and value of the next
|
|
argument in the call.
|
|
The parameter
|
|
.I ap
|
|
is the
|
|
.I va_list
|
|
.I ap
|
|
initialized by
|
|
.BR va_start ().
|
|
Each call to
|
|
.BR va_arg ()
|
|
modifies
|
|
.I ap
|
|
so that the next call returns the next argument.
|
|
The parameter
|
|
.I type
|
|
is a type name specified so that the type of a pointer to an object that
|
|
has the specified type can be obtained simply by adding a * to
|
|
.IR type .
|
|
.PP
|
|
The first use of the
|
|
.BR va_arg ()
|
|
macro after that of the
|
|
.BR va_start ()
|
|
macro returns the argument after
|
|
.IR last .
|
|
Successive invocations return the values of the remaining arguments.
|
|
.PP
|
|
If there is no next argument, or if
|
|
.I type
|
|
is not compatible with the type of the actual next argument (as promoted
|
|
according to the default argument promotions), random errors will occur.
|
|
.PP
|
|
If
|
|
.I ap
|
|
is passed to a function that uses
|
|
.BI va_arg( ap , type )
|
|
then the value of
|
|
.I ap
|
|
is undefined after the return of that function.
|
|
.SS va_end()
|
|
Each invocation of
|
|
.BR va_start ()
|
|
must be matched by a corresponding invocation of
|
|
.BR va_end ()
|
|
in the same function.
|
|
After the call
|
|
.BI va_end( ap )
|
|
the variable
|
|
.I ap
|
|
is undefined.
|
|
Multiple traversals of the list, each
|
|
bracketed by
|
|
.BR va_start ()
|
|
and
|
|
.BR va_end ()
|
|
are possible.
|
|
.BR va_end ()
|
|
may be a macro or a function.
|
|
.SS va_copy()
|
|
.\" Proposal from clive@demon.net, 1997-02-28
|
|
An obvious implementation would have a
|
|
.I va_list
|
|
be a pointer to the stack frame of the variadic function.
|
|
In such a setup (by far the most common) there seems
|
|
nothing against an assignment
|
|
.in +4n
|
|
.nf
|
|
|
|
va_list aq = ap;
|
|
|
|
.fi
|
|
.in
|
|
Unfortunately, there are also systems that make it an
|
|
array of pointers (of length 1), and there one needs
|
|
.in +4n
|
|
.nf
|
|
|
|
va_list aq;
|
|
*aq = *ap;
|
|
|
|
.fi
|
|
.in
|
|
Finally, on systems where parameters are passed in registers,
|
|
it may be necessary for
|
|
.BR va_start ()
|
|
to allocate memory, store the parameters there, and also
|
|
an indication of which parameter is next, so that
|
|
.BR va_arg ()
|
|
can step through the list.
|
|
Now
|
|
.BR va_end ()
|
|
can free the allocated memory again.
|
|
To accommodate this situation, C99 adds a macro
|
|
.BR va_copy (),
|
|
so that the above assignment can be replaced by
|
|
.in +4n
|
|
.nf
|
|
|
|
va_list aq;
|
|
va_copy(aq, ap);
|
|
\&...
|
|
va_end(aq);
|
|
|
|
.fi
|
|
.in
|
|
Each invocation of
|
|
.BR va_copy ()
|
|
must be matched by a corresponding invocation of
|
|
.BR va_end ()
|
|
in the same function.
|
|
Some systems that do not supply
|
|
.BR va_copy ()
|
|
have
|
|
.B __va_copy
|
|
instead, since that was the name used in the draft proposal.
|
|
.SH "CONFORMING TO"
|
|
The
|
|
.BR va_start (),
|
|
.BR va_arg (),
|
|
and
|
|
.BR va_end ()
|
|
macros conform to C89.
|
|
C99 defines the
|
|
.BR va_copy ()
|
|
macro.
|
|
.SH NOTES
|
|
These macros are
|
|
.I not
|
|
compatible with the historic macros they replace.
|
|
A backward compatible version can be found in the include file
|
|
.IR <varargs.h> .
|
|
.PP
|
|
The historic setup is:
|
|
.in +4n
|
|
.nf
|
|
|
|
#include <varargs.h>
|
|
|
|
void
|
|
foo(va_alist)
|
|
va_dcl
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap);
|
|
while (...) {
|
|
...
|
|
x = va_arg(ap, type);
|
|
...
|
|
}
|
|
va_end(ap);
|
|
}
|
|
|
|
.fi
|
|
.in
|
|
On some systems,
|
|
.I va_end
|
|
contains a closing \(aq}\(aq matching a \(aq{\(aq in
|
|
.IR va_start ,
|
|
so that both macros must occur in the same function, and in a way
|
|
that allows this.
|
|
.SH BUGS
|
|
Unlike the
|
|
.B varargs
|
|
macros, the
|
|
.B stdarg
|
|
macros do not permit programmers to code a function with no fixed
|
|
arguments.
|
|
This problem generates work mainly when converting
|
|
.B varargs
|
|
code to
|
|
.B stdarg
|
|
code, but it also creates difficulties for variadic functions that wish to
|
|
pass all of their arguments on to a function that takes a
|
|
.I va_list
|
|
argument, such as
|
|
.BR vfprintf (3).
|
|
.SH EXAMPLE
|
|
The function
|
|
.I foo
|
|
takes a string of format characters and prints out the argument associated
|
|
with each format character based on the type.
|
|
.nf
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
|
|
void
|
|
foo(char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
int d;
|
|
char c, *s;
|
|
|
|
va_start(ap, fmt);
|
|
while (*fmt)
|
|
switch (*fmt++) {
|
|
case \(aqs\(aq: /* string */
|
|
s = va_arg(ap, char *);
|
|
printf("string %s\en", s);
|
|
break;
|
|
case \(aqd\(aq: /* int */
|
|
d = va_arg(ap, int);
|
|
printf("int %d\en", d);
|
|
break;
|
|
case \(aqc\(aq: /* char */
|
|
/* need a cast here since va_arg only
|
|
takes fully promoted types */
|
|
c = (char) va_arg(ap, int);
|
|
printf("char %c\en", c);
|
|
break;
|
|
}
|
|
va_end(ap);
|
|
}
|
|
.fi
|