man-pages/man3/stdarg.3.html
2021-03-31 01:06:50 +01:00

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">&nbsp;</A>
<H2>NAME</H2>
stdarg, va_start, va_arg, va_end, va_copy - variable argument lists
<A NAME="lbAC">&nbsp;</A>
<H2>SYNOPSIS</H2>
<B>#include &lt;<A HREF="file:///usr/include/stdarg.h">stdarg.h</A>&gt;</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">&nbsp;</A>
<H2>DESCRIPTION</H2>
A function may be called with a varying number of arguments of varying
types.
The include file
<I>&lt;<A HREF="file:///usr/include/stdarg.h">stdarg.h</A>&gt;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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 &lt;<A HREF="file:///usr/include/stdio.h">stdio.h</A>&gt;
#include &lt;<A HREF="file:///usr/include/stdarg.h">stdarg.h</A>&gt;
<P>
void
foo(char *fmt, ...) /* '...' is C syntax for a variadic function */
<P>
{
<BR>&nbsp;&nbsp;&nbsp;&nbsp;va_list&nbsp;ap;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;d;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;c,&nbsp;*s;
<P>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;va_start(ap,&nbsp;fmt);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(*fmt)
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(*fmt++)&nbsp;{
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;'s':&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;string&nbsp;*/
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;=&nbsp;va_arg(ap,&nbsp;char&nbsp;*);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;string&nbsp;%s\n&quot;,&nbsp;s);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;'d':&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;int&nbsp;*/
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d&nbsp;=&nbsp;va_arg(ap,&nbsp;int);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;int&nbsp;%d\n&quot;,&nbsp;d);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;'c':&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;char&nbsp;*/
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;need&nbsp;a&nbsp;cast&nbsp;here&nbsp;since&nbsp;va_arg&nbsp;only
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;takes&nbsp;fully&nbsp;promoted&nbsp;types&nbsp;*/
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;=&nbsp;(char)&nbsp;va_arg(ap,&nbsp;int);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;char&nbsp;%c\n&quot;,&nbsp;c);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
<BR>&nbsp;&nbsp;&nbsp;&nbsp;va_end(ap);
}
<A NAME="lbAM">&nbsp;</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">&nbsp;</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>