va_arg, va_end, va_start

Description

Access variable-argument lists.

#include <stdarg.h> Required for ANSI compatibility  
#include <varargs.h> Required for UNIX V compatibility  
#include <stdio.h>    

type va_arg( va_list arg_ptr, type );

void va_end( va_list arg_ptr );

void va_start( va_list arg_ptr ); UNIX version

void va_start( va_list arg_ptr, prev_param ); ANSI

arg_ptr Pointer to list of arguments  
prev_param Parameter preceding first optional argument (ANSI only)  
type Type of argument to be retrieved  

Remarks

The va_arg, va_end, and va_start macros provide a portable way to access the arguments to a function when the function takes a variable number of arguments. Two versions of the macros are available: the macros defined in STDARG.H conform to the ANSI C standard, and the macros defined in VARARGS.H are compatible with the UNIX System V definition. The macros are listed below:

Macro Description

va_alist Name of parameter to called function (UNIX version only)
va_arg Macro to retrieve current argument
va_dcl Declaration of va_alist (UNIX version only)
va_end Macro to reset arg_ptr
va_list The typedef for the pointer to list of arguments
va_start Macro to set arg_ptr to beginning of list of optional arguments (UNIX version only)

Both versions of the macros assume that the function takes a fixed number of required arguments, followed by a variable number of optional arguments. The required arguments are declared as ordinary parameters to the function and can be accessed through the parameter names. The optional arguments are accessed through the macros in STDARG.H or VARARGS.H, which set a pointer to the first optional argument in the argument list, retrieve arguments from the list, and reset the pointer when argument processing is completed.

The ANSI C standard macros, defined in STDARG.H, are used as follows:

1.All required arguments to the function are declared as parameters in the usual way. The va_dcl macro is not used with the STDARG.H macros.

2.The va_start macro sets arg_ptr to the first optional argument in the list of arguments passed to the function. The argument arg_ptr must have va_list type. The argument prev_param is the name of the required parameter immediately preceding the first optional argument in the argument list. If prev_param is declared with the register storage class, the macro's behavior is undefined. The va_start macro must be used before va_arg is used for the first time.

3.The va_arg macro does the following:

Retrieves a value of type from the location given by arg_ptr

Increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts

The va_arg macro can be used any number of times within the function to retrieve arguments from the list.After all arguments have been retrieved, va_end resets the pointer to NULL.

The UNIX System V macros, defined in VARARGS.H, operate in a slightly different manner, as follows:

1.Any required arguments to the function can be declared as parameters in the usual way.

2.The last (or only) parameter to the function represents the list of optional arguments. This parameter must be named va_alist (not to be confused with va_list, which is defined as the type of va_alist).

3.The va_dcl macro appears after the function definition and before the opening left brace of the function. This macro is defined as a complete declaration of the va_alist parameter, including the terminating semicolon; therefore, no semicolon should follow va_dcl.

4.Within the function, the va_start macro sets arg_ptr to the beginning of the list of optional arguments passed to the function. The va_start macro must be used before va_arg is used for the first time. The argument arg_ptr must have va_list type.

5.The va_arg macro does the following:

Retrieves a value of type from the location given by arg_ptr

Increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts

The va_arg macro can be used any number of times within the function to retrieve the arguments from the list.After all arguments have been retrieved, va_end resets the pointer to NULL.

Return Value

The va_arg macro returns the current argument; va_start and va_end do not return values.

Compatibility

Standards:ANSI, UNIX

16-Bit:DOS, QWIN, WIN, WIN DLL

32-Bit:DOS32X

See Also

vfprintf

Example

/* VA.C: The program below illustrates passing a variable number of arguments

* using the following macros:

* va_start va_arg va_end

* va_list va_decl (UNIX only)

*/

#include <stdio.h>

#define ANSI /* Comment out for UNIX version */

#ifdef ANSI /* ANSI compatible version */

#include <stdarg.h>

int average( int first, ... );

#else /* UNIX compatible version */

#include <varargs.h>

int average( va_list );

#endif

void main( void )

{

/* Call with 3 integers (-1 is used as terminator). */

printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

/* Call with 4 integers. */

printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

/* Call with just -1 terminator. */

printf( "Average is: %d\n", average( -1 ) );

}

/* Returns the average of a variable list of integers. */

#ifdef ANSI /* ANSI compatible version */

int average( int first, ... )

{

int count = 0, sum = 0, i = first;

va_list marker;

va_start( marker, first ); /* Initialize variable arguments. */

while( i != -1 )

{

sum += i;

count++;

i = va_arg( marker, int);

}

va_end( marker ); /* Reset variable arguments. */

return( sum ? (sum / count) : 0 );

}

#else /* UNIX compatible version must use old-style definition. */

int average( va_alist )

va_dcl

{

int i, count, sum;

va_list marker;

va_start( marker ); /* Initialize variable arguments. */

for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )

sum += i;

va_end( marker ); /* Reset variable arguments. */

return( sum ? (sum / count) : 0 );

}

#endif

Output

Average is: 3

Average is: 8

Average is: 0