Standards / Extensions | C or C++ | Dependencies |
---|---|---|
ISO C |
both |
#include <stdarg.h>
var_type va_arg(va_list arg_ptr, var_type);
void va_end(va_list arg_ptr);
void va_start(va_list arg_ptr, variable_name);
#define _ISOC99_SOURCE
#include <stdarg.h>
var_type va_arg(va_list arg_ptr, var_type);
void va_end(va_list arg_ptr);
void va_start(va_list arg_ptr, variable_name);
void va_copy(va_list dest, va_list src);
The va_arg(), va_end(), and va_start() macros access the arguments to a function when it takes a fixed number of required arguments and a variable number of optional arguments. You declare required arguments as ordinary parameters to the function and access the arguments through the parameter names.
The va_start() macro initializes the arg_ptr pointer for subsequent calls to va_arg() and va_end().
The argument variable_name is the identifier of the rightmost named parameter in the parameter list (preceding , …). Use the va_start() macro before the va_arg() macro. Corresponding va_start() and va_end() macro calls must be in the same function. If variable_name is declared as a register, with a function or an array type, or with a type that is not compatible with the type that results after application of the default argument promotions, then the behavior is undefined.
The va_arg() macro retrieves a value of the given var_type from the location given by arg_ptr and increases arg_ptr to point to the next argument in the list. The va_arg() macro can retrieve arguments from the list any number of times within the function.
The macros also provide fixed-point decimal support under z/OS® XL C. The sizeof(xx) operator is used to determine the size and type casting that is used to generate the values. Therefore, a call, such as, x = va_arg(ap, _Decimal(5,2)); is valid. The size of a fixed-point decimal number, however, cannot be made a variable. Therefore, a call, such as, z = va_arg(ap, _Decimal(x,y)) where x = 5 and y = 2 is invalid.
The va_end() macro is needed by some systems to indicate the end of parameter scanning.
va_start() and va_arg() do not work with parameter lists of functions whose linkages were changed with the #pragma linkage directive.
stdarg.h and varargs.h are mutually exclusive. Whichever #include comes first, determines the form of macro that is visible.
The type definition for the va_list type is normally "char *va_list[2]". Some applications (especially ported applications) require that the va_list type be defined as "char *va_list". This alternate va_list type is available if the user defines the feature test macro _VARARG_EXT_ before the inclusion of any system header file. If the _VARARG_EXT_ feature test macro is defined, va_list will be typed as char * va_list, and the functions vprintf(), vfprintf(), vsprintf(), and vswprintf() will use this alternate va_list type.
The va_copy() function creates a copy (dest) of a variable of type va_list (src). The copy appear as if it has gone through a va_start() and the exact set of sequences of va_arg() as that of src.
After va_copy() initializes dest, the va_copy() macro shall not be invoked to reinitialize dest without an intervening invocation of the va_end() macro for the same dest.
The va_arg() macro returns the current argument.
The va_end(), va_copy(), and va_start() macros return no values.
⁄* CELEBV01
This example passes a variable number of arguments to a function,
stores each argument in an array, and prints each argument.
*⁄
#include <stdio.h>
#include <stdarg.h>
void vout(int max, ...);
int main(void)
{
vout(3, "Sat", "Sun", "Mon");
printf("\n");
vout(5, "Mon", "Tues", "Wed", "Thurs", "Fri");
}
void vout(int max, ...)
{
va_list arg_ptr;
int args = 0;
char *days[7];
va_start(arg_ptr, max);
while(args < max)
{
days[args] = va_arg(arg_ptr, char *);
printf("Day: %s \n", days[args++]);
}
va_end(arg_ptr);
}
Day: Sat
Day: Sun
Day: Mon
Day: Mon
Day: Tues
Day: Wed
Day: Thurs
Day: Fri
/* This example uses a variable number of arguments for
fixed-point decimal data types.
The example works in z/OS XL C only.
*/
#include <stdio.h>
#include <stdarg.h>
#include <decimal.h>
void vprnt(int, ...);
int main(void) {
int i = 168;
decimal(10,2) pd01 = 12345678.12d;
decimal(20,5) pd02 = -987.65d;
decimal(31,20) pd03 = 12345678901.12345678900987654321d;
int j = 135;
vprnt(0, i, pd01, pd02, pd03, j);
return(0);
}
void vprnt(int whichcase, ...) {
va_list arg_ptr;
int m, n;
decimal(10,2) va01;
decimal(20,5) va02;
decimal(31,20) va03;
va_start(arg_ptr, whichcase);
switch (whichcase) {
case 0:
m = va_arg(arg_ptr, int);
va01 = va_arg(arg_ptr, decimal(10,2));
va02 = va_arg(arg_ptr, decimal(20,5));
va03 = va_arg(arg_ptr, decimal(31,20));
n = va_arg(arg_ptr, int);
printf("m = %d\n", m);
printf("va01 = %D(10,2)\n", va01);
printf("va02 = %D(20,5)\n", va02);
printf("va03 = %D(31,20)\n", va03);
printf("n = %d\n", n);
break;
default:
printf("Illegal case number : %d\n", whichcase);
}
va_end(arg_ptr);
}
m = 168
va01 = 12345678.12
va02 = -987.65000
va03 = 12345678901.12345678900987654321
n = 135
⁄* CELEBV02
These examples use the _XOPEN_SOURCE feature test macro,
This ecample passes a variable number of arguments to a function,
stores each argument in an array, and prints each argument.
*⁄
#define _XOPEN_SOURCE
#include <stdio.h>
#include <varargs.h>
void vout(va_alist)
va_dcl
{
va_list arg_ptr;
int args = 0;
int max;
char *days[7];
va_start(arg_ptr);
max = va_arg(arg_ptr, int);
while(args < max) {
days[args] = va_arg(arg_ptr, char *);
printf("Days: %s \n", days[args++]);
}
va_end(arg_ptr);
}
int main(void)
{
vout(3,"Sat","Sun","Mon");
printf("\n");
vout(5,"Mon","Tues","Wed","Thurs","Fri");
}
/* This example uses a variable number of arguments for
fixed-point decimal data types.
The example works in z/OS XL C only.
*/
#define _XOPEN_SOURCE
#include <stdio.h>
#include <varargs.h>
#include <decimal.h>
void vprnt(va_alist)
va_dcl
{
va_list arg_ptr;
int m, n, whichcase;
decimal(10,2) va01;
decimal(20,5) va02;
decimal(31,20) va03;
va_start(arg_ptr);
whichcase = va_arg(arg_ptr, int);
switch (whichcase) {
case 0:
m = va_arg(arg_ptr, int);
va01 = va_arg(arg_ptr, decimal(10,2));
va02 = va_arg(arg_ptr, decimal(20,5));
va03 = va_arg(arg_ptr, decimal(31,20));
n = va_arg(arg_ptr, int);
printf("m = %d\n", m);
printf("va01 = %D(10,2)\n", va01);
printf("va02 = %D(20,5)\n", va02);
printf("va03 = %D(31,20)\n", va03);
printf("n = %d\n", n);
break;
default:
printf("Illegal case number : %d\n", whichcase);
}
va_end(arg_ptr);
}
int main(void) {
int i = 168;
decimal(10,2) pd01 = 12345678.12d;
decimal(20,5) pd02 = -987.65d;
decimal(31,20) pd03 = 12345678901.12345678900987654321d;
int j = 135;
vprnt(0, i, pd01, pd02, pd03, j);
return(0);
}
}
#define _ISOC99_SOURCE
#include <stdio.h>
#include <stdarg.h>
void prnt(int max, ...);
int main(void)
{
prnt(8, "0", "1", "1", "2", "3", "5", "8", "13");
}
void prnt(int max, ...)
{
va_list src;
va_list dest;
int args = 0;
char *fib[8];
va_start(src, max);
va_copy(dest, src);
while(args < max) {
fib[args] = va_arg(dest, char *);
printf("fib[%d]: %s \n", args, fib[args++]);
}
va_end(dest);
}
Output
fib[0]: 0
fib[1]: 1
fib[2]: 1
fib[3]: 2
fib[4]: 3
fib[5]: 5
fib[6]: 8
fib[7]: 13