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