JTC1/SC22/WG14
N592
WG14/N592 X3J11/96-056
Proposal UK009b - Introduction of a va_list copying function
============================================================
Summary
-------
This proposal provides an additional facility to make variable arguments
easier to use: a function to copy a va_list.
Conformance
-----------
This proposal includes a new identifier. The present proposal uses names
in the reserved namespace in order to avoid affecting strictly conforming
programs. If more attractive names not in the reserved namespace are used
instead, some strictly conforming programs will be affected.
No other aspect of the proposal affects any strictly conforming program.
Discussion
----------
Sometimes processing variable arguments would be easier if the state of
processing could be copied, and then reverted to at a later point. However,
there is currently no way to do this. This proposal adds such a copying
mechanism.
There is no way to do this operation in C89. It is quite possible that a
value of type va_list includes a pointer to allocated memory. If so, then
that memory needs to be copied as well. There is, obviously, no way for a
strictly-conforming program to determine what is necessary to do this.
WG14 will have to decide whether the new identifier defined is "va_copy"
or "__va_copy". Apart from this, this proposal contains the required
changes to be made to C9X draft 6.
Detailed proposal
-----------------
In subclause 7.9 (7.8 in C89), replace:
The header <stdarg.h> declares a type and defines three macros,
with:
The header <stdarg.h> declares a type and defines four macros,
and replace:
which is a type suitable for holding information needed by
the macros va_start, va_arg, and va_end.
with:
which is a type suitable for holding information needed by
the macros va_start, va_arg, va_end, and __va_copy.
In subclause 7.9.1 (7.8.1 in C89), replace:
It is unspecified whether va_end is a macro or
an identifier declared with external linkage. If a macro
definition is suppressed in order to access an actual
function, or a program defines an external identifier with
the name va_end, the behavior is undefined.
with:
It is unspecified whether va_end and __va_copy are macros or
identifiers declared with external linkage. If a macro
definition is suppressed in order to access an actual
function, or a program defines an external identifier with
the name va_end or __va_copy, the behavior is undefined.
Add a new subclause 7.9.1.4 before the example:
7.9.1.4 The __va_copy macro
Synopsis
#include <stdarg.h>
void __va_copy (va_list dest, va_list src);
Description
The __va_copy function or macro makes the va_list dest be a copy of
the va_list src, as if the va_start macro had been applied to it
followed by the same sequence of uses of the va_arg macro as
had previously been used to reach the present state of src.
Returns
The __va_copy function or macro returns no value.
Add a second example:
Example
The function f3 is similar, but saves the status of the variable argument
list after the indicated number of arguments; after f2 has been called
once with the whole list, the trailing part of the list is gathered
again and passed to function f4.
#include <stdarg.h>
#define MAXARGS 31
void f3(int n_ptrs, int f4_after, ...)
{
va_list ap, ap_save;
char *array[MAXARGS];
int ptr_no = 0;
if (n_ptrs > MAXARGS)
n_ptrs = MAXARGS;
va_start(ap, n_ptrs);
while (ptr_no < n_ptrs)
{
array[ptr_no++] = va_arg(ap, char *);
if (ptr_no == f4_after)
__va_copy(ap_save, ap);
}
va_end(ap);
f2(n_ptrs, array);
/* Now process the saved copy */
n_ptrs -= f4_after;
ptr_no = 0;
while (ptr_no < n_ptrs)
array[ptr_no++] = va_arg(ap_save, char *);
va_end(ap_save);
f4(n_ptrs, array);
}