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 declares a type and defines three macros, with: The header 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 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 #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); }