426 lines
9.6 KiB
HTML
426 lines
9.6 KiB
HTML
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML><HEAD><TITLE>Man page of STDARG</TITLE>
|
|
</HEAD><BODY>
|
|
<H1>STDARG</H1>
|
|
Section: Linux Programmer's Manual (3)<BR>Updated: 2019-05-09<BR><A HREF="#index">Index</A>
|
|
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
|
|
|
<A NAME="lbAB"> </A>
|
|
<H2>NAME</H2>
|
|
|
|
stdarg, va_start, va_arg, va_end, va_copy - variable argument lists
|
|
<A NAME="lbAC"> </A>
|
|
<H2>SYNOPSIS</H2>
|
|
|
|
<B>#include <<A HREF="file:///usr/include/stdarg.h">stdarg.h</A>></B>
|
|
|
|
<P>
|
|
|
|
<B>void va_start(va_list </B><I>ap</I><B>, </B><I>last</I><B>);</B>
|
|
|
|
<BR>
|
|
|
|
<I>type</I><B> va_arg(va_list </B><I>ap</I><B>, </B><I>type</I><B>);</B>
|
|
|
|
<BR>
|
|
|
|
<B>void va_end(va_list </B><I>ap</I><B>);</B>
|
|
|
|
<BR>
|
|
|
|
<B>void va_copy(va_list </B><I>dest</I><B>, va_list </B><I>src</I><B>);</B>
|
|
|
|
<A NAME="lbAD"> </A>
|
|
<H2>DESCRIPTION</H2>
|
|
|
|
A function may be called with a varying number of arguments of varying
|
|
types.
|
|
The include file
|
|
<I><<A HREF="file:///usr/include/stdarg.h">stdarg.h</A>></I>
|
|
|
|
declares a type
|
|
<I>va_list</I>
|
|
|
|
and defines three macros for stepping through a list of arguments whose
|
|
number and types are not known to the called function.
|
|
<P>
|
|
|
|
The called function must declare an object of type
|
|
<I>va_list</I>
|
|
|
|
which is used by the macros
|
|
<B>va_start</B>(),
|
|
|
|
<B>va_arg</B>(),
|
|
|
|
and
|
|
<B>va_end</B>().
|
|
|
|
<A NAME="lbAE"> </A>
|
|
<H3>va_start()</H3>
|
|
|
|
The
|
|
<B>va_start</B>()
|
|
|
|
macro initializes
|
|
<I>ap</I>
|
|
|
|
for subsequent use by
|
|
<B>va_arg</B>()
|
|
|
|
and
|
|
<B>va_end</B>(),
|
|
|
|
and must be called first.
|
|
<P>
|
|
|
|
The argument
|
|
<I>last</I>
|
|
|
|
is the name of the last argument before the variable argument list, that is,
|
|
the last argument of which the calling function knows the type.
|
|
<P>
|
|
|
|
Because the address of this argument may be used in the
|
|
<B>va_start</B>()
|
|
|
|
macro, it should not be declared as a register variable,
|
|
or as a function or an array type.
|
|
<A NAME="lbAF"> </A>
|
|
<H3>va_arg()</H3>
|
|
|
|
The
|
|
<B>va_arg</B>()
|
|
|
|
macro expands to an expression that has the type and value of the next
|
|
argument in the call.
|
|
The argument
|
|
<I>ap</I>
|
|
|
|
is the
|
|
<I>va_list</I>
|
|
|
|
<I>ap</I>
|
|
|
|
initialized by
|
|
<B>va_start</B>().
|
|
|
|
Each call to
|
|
<B>va_arg</B>()
|
|
|
|
modifies
|
|
<I>ap</I>
|
|
|
|
so that the next call returns the next argument.
|
|
The argument
|
|
<I>type</I>
|
|
|
|
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
|
|
<I>type</I>.
|
|
|
|
<P>
|
|
|
|
The first use of the
|
|
<B>va_arg</B>()
|
|
|
|
macro after that of the
|
|
<B>va_start</B>()
|
|
|
|
macro returns the argument after
|
|
<I>last</I>.
|
|
|
|
Successive invocations return the values of the remaining arguments.
|
|
<P>
|
|
|
|
If there is no next argument, or if
|
|
<I>type</I>
|
|
|
|
is not compatible with the type of the actual next argument (as promoted
|
|
according to the default argument promotions), random errors will occur.
|
|
<P>
|
|
|
|
If
|
|
<I>ap</I>
|
|
|
|
is passed to a function that uses
|
|
<B>va_arg(</B><I>ap</I><B>,</B><I>type</I><B>),</B>
|
|
|
|
then the value of
|
|
<I>ap</I>
|
|
|
|
is undefined after the return of that function.
|
|
<A NAME="lbAG"> </A>
|
|
<H3>va_end()</H3>
|
|
|
|
Each invocation of
|
|
<B>va_start</B>()
|
|
|
|
must be matched by a corresponding invocation of
|
|
<B>va_end</B>()
|
|
|
|
in the same function.
|
|
After the call
|
|
<B>va_end(</B><I>ap</I><B>)</B>
|
|
|
|
the variable
|
|
<I>ap</I>
|
|
|
|
is undefined.
|
|
Multiple traversals of the list, each
|
|
bracketed by
|
|
<B>va_start</B>()
|
|
|
|
and
|
|
<B>va_end</B>()
|
|
|
|
are possible.
|
|
<B>va_end</B>()
|
|
|
|
may be a macro or a function.
|
|
<A NAME="lbAH"> </A>
|
|
<H3>va_copy()</H3>
|
|
|
|
The
|
|
<B>va_copy</B>()
|
|
|
|
macro copies the (previously initialized) variable argument list
|
|
<I>src</I>
|
|
|
|
to
|
|
<I>dest</I>.
|
|
|
|
The behavior is as if
|
|
<B>va_start</B>()
|
|
|
|
were applied to
|
|
<I>dest</I>
|
|
|
|
with the same
|
|
<I>last</I>
|
|
|
|
argument, followed by the same number of
|
|
<B>va_arg</B>()
|
|
|
|
invocations that was used to reach the current state of
|
|
<I>src</I>.
|
|
|
|
<P>
|
|
|
|
|
|
An obvious implementation would have a
|
|
<I>va_list</I>
|
|
|
|
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
|
|
<P>
|
|
|
|
|
|
|
|
va_list aq = ap;
|
|
|
|
|
|
<P>
|
|
|
|
Unfortunately, there are also systems that make it an
|
|
array of pointers (of length 1), and there one needs
|
|
<P>
|
|
|
|
|
|
|
|
va_list aq;
|
|
*aq = *ap;
|
|
|
|
|
|
<P>
|
|
|
|
Finally, on systems where arguments are passed in registers,
|
|
it may be necessary for
|
|
<B>va_start</B>()
|
|
|
|
to allocate memory, store the arguments there, and also
|
|
an indication of which argument is next, so that
|
|
<B>va_arg</B>()
|
|
|
|
can step through the list.
|
|
Now
|
|
<B>va_end</B>()
|
|
|
|
can free the allocated memory again.
|
|
To accommodate this situation, C99 adds a macro
|
|
<B>va_copy</B>(),
|
|
|
|
so that the above assignment can be replaced by
|
|
<P>
|
|
|
|
|
|
|
|
va_list aq;
|
|
va_copy(aq, ap);
|
|
...
|
|
va_end(aq);
|
|
|
|
|
|
<P>
|
|
|
|
Each invocation of
|
|
<B>va_copy</B>()
|
|
|
|
must be matched by a corresponding invocation of
|
|
<B>va_end</B>()
|
|
|
|
in the same function.
|
|
Some systems that do not supply
|
|
<B>va_copy</B>()
|
|
|
|
have
|
|
<B>__va_copy</B>
|
|
|
|
instead, since that was the name used in the draft proposal.
|
|
<A NAME="lbAI"> </A>
|
|
<H2>ATTRIBUTES</H2>
|
|
|
|
For an explanation of the terms used in this section, see
|
|
<B><A HREF="/cgi-bin/man/man2html?7+attributes">attributes</A></B>(7).
|
|
|
|
<TABLE BORDER>
|
|
<TR VALIGN=top><TD><B>Interface</B></TD><TD><B>Attribute</B></TD><TD><B>Value</B><BR></TD></TR>
|
|
<TR VALIGN=top><TD>
|
|
<B>va_start</B>(),
|
|
|
|
<B>va_end</B>(),
|
|
|
|
<B>va_copy</B>()
|
|
|
|
</TD><TD>Thread safety</TD><TD>MT-Safe<BR></TD></TR>
|
|
<TR VALIGN=top><TD>
|
|
<B>va_arg</B>()
|
|
|
|
</TD><TD>Thread safety</TD><TD>MT-Safe race:ap<BR></TD></TR>
|
|
</TABLE>
|
|
|
|
<A NAME="lbAJ"> </A>
|
|
<H2>CONFORMING TO</H2>
|
|
|
|
The
|
|
<B>va_start</B>(),
|
|
|
|
<B>va_arg</B>(),
|
|
|
|
and
|
|
<B>va_end</B>()
|
|
|
|
macros conform to C89.
|
|
C99 defines the
|
|
<B>va_copy</B>()
|
|
|
|
macro.
|
|
<A NAME="lbAK"> </A>
|
|
<H2>BUGS</H2>
|
|
|
|
Unlike the historical
|
|
<B>varargs</B>
|
|
|
|
macros, the
|
|
<B>stdarg</B>
|
|
|
|
macros do not permit programmers to code a function with no fixed
|
|
arguments.
|
|
This problem generates work mainly when converting
|
|
<B>varargs</B>
|
|
|
|
code to
|
|
<B>stdarg</B>
|
|
|
|
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</I>
|
|
|
|
argument, such as
|
|
<B><A HREF="/cgi-bin/man/man2html?3+vfprintf">vfprintf</A></B>(3).
|
|
|
|
<A NAME="lbAL"> </A>
|
|
<H2>EXAMPLE</H2>
|
|
|
|
The function
|
|
<I>foo</I>
|
|
|
|
takes a string of format characters and prints out the argument associated
|
|
with each format character based on the type.
|
|
<P>
|
|
|
|
|
|
#include <<A HREF="file:///usr/include/stdio.h">stdio.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdarg.h">stdarg.h</A>>
|
|
<P>
|
|
void
|
|
foo(char *fmt, ...) /* '...' is C syntax for a variadic function */
|
|
<P>
|
|
{
|
|
<BR> va_list ap;
|
|
<BR> int d;
|
|
<BR> char c, *s;
|
|
<P>
|
|
<BR> va_start(ap, fmt);
|
|
<BR> while (*fmt)
|
|
<BR> switch (*fmt++) {
|
|
<BR> case 's': /* string */
|
|
<BR> s = va_arg(ap, char *);
|
|
<BR> printf("string %s\n", s);
|
|
<BR> break;
|
|
<BR> case 'd': /* int */
|
|
<BR> d = va_arg(ap, int);
|
|
<BR> printf("int %d\n", d);
|
|
<BR> break;
|
|
<BR> case 'c': /* char */
|
|
<BR> /* need a cast here since va_arg only
|
|
<BR> takes fully promoted types */
|
|
<BR> c = (char) va_arg(ap, int);
|
|
<BR> printf("char %c\n", c);
|
|
<BR> break;
|
|
<BR> }
|
|
<BR> va_end(ap);
|
|
}
|
|
|
|
<A NAME="lbAM"> </A>
|
|
<H2>COLOPHON</H2>
|
|
|
|
This page is part of release 5.05 of the Linux
|
|
<I>man-pages</I>
|
|
|
|
project.
|
|
A description of the project,
|
|
information about reporting bugs,
|
|
and the latest version of this page,
|
|
can be found at
|
|
<A HREF="https://www.kernel.org/doc/man-pages/.">https://www.kernel.org/doc/man-pages/.</A>
|
|
<P>
|
|
|
|
<HR>
|
|
<A NAME="index"> </A><H2>Index</H2>
|
|
<DL>
|
|
<DT id="1"><A HREF="#lbAB">NAME</A><DD>
|
|
<DT id="2"><A HREF="#lbAC">SYNOPSIS</A><DD>
|
|
<DT id="3"><A HREF="#lbAD">DESCRIPTION</A><DD>
|
|
<DL>
|
|
<DT id="4"><A HREF="#lbAE">va_start()</A><DD>
|
|
<DT id="5"><A HREF="#lbAF">va_arg()</A><DD>
|
|
<DT id="6"><A HREF="#lbAG">va_end()</A><DD>
|
|
<DT id="7"><A HREF="#lbAH">va_copy()</A><DD>
|
|
</DL>
|
|
<DT id="8"><A HREF="#lbAI">ATTRIBUTES</A><DD>
|
|
<DT id="9"><A HREF="#lbAJ">CONFORMING TO</A><DD>
|
|
<DT id="10"><A HREF="#lbAK">BUGS</A><DD>
|
|
<DT id="11"><A HREF="#lbAL">EXAMPLE</A><DD>
|
|
<DT id="12"><A HREF="#lbAM">COLOPHON</A><DD>
|
|
</DL>
|
|
<HR>
|
|
This document was created by
|
|
<A HREF="/cgi-bin/man/man2html">man2html</A>,
|
|
using the manual pages.<BR>
|
|
Time: 00:05:57 GMT, March 31, 2021
|
|
</BODY>
|
|
</HTML>
|