is the identifier of the rightmost parameter in the variable parameter list in the function definition (the one just before the ellipses ie., ", ...").
(type *) va_arg(va_list pvar, type);
pvar
is a pointer to variable argument list; and type
is the type name of the next argument to be returned.
va_arg()
expands to an expression that has the type and value of the next argument in the call. The parameter pvar
must be initialized by va_start()
. Each invocation of va_arg()
modifies pvar
so that the values of successive arguments are returned in turn. The parameter type
is the type name of the next argument to be returned.
void va_end(va_list pvar);
pvar
is a pointer to variable argument list
The va_end()
macro is used to clean up. It invalidates pvar
for use (unless va_start()
is invoked again).
Example:
The following example creates a variable length argument routine to return the maximum of the data being passed to the routine, maximum
.
% more maximum.c
#include <stdio.h>
#include <stdarg.h>
float maximum (const char *format, ...) {
int maxint = 0, temp_maxint = 0;
float maxfloat = 0.0, temp_maxfloat = 0.0;
va_list ap; /* declare an argument pointer to a variable arg list */
va_start(ap, format); /* initialize arg pointer using last known arg */
const char *p = format;
while (*p) {
switch(*p) {
case 'i':
temp_maxint = va_arg(ap, int);
if (temp_maxint > maxint) {
maxint = temp_maxint;
}
++p;
continue;
case 'f':
temp_maxfloat = va_arg(ap, float);
if (temp_maxfloat > maxfloat) {
maxfloat = temp_maxfloat;
}
++p;
continue;
default:
++p;
continue;
} // switch
} // while
va_end(ap); /* restore any special stack manipulations */
if (*format == 'i') {
return (maxint);
} else if (*format == 'f') {
return (maxfloat);
}
return (0);
} // maximum
int main() {
float max;
max = maximum("iiiii", 431, 276, 3982, 5, 54);
printf("\nMaximum of 431, 276, 3982, 5, 54 = %d", (int)max);
max = maximum("fff", 12.2, 1.3, 54.43);
printf("\nMaximum of 12.2, 1.3, 54.43 = %f", max);
max = maximum("iiiiiiiiii", 43, 45, 65, 12, 32, 78, 9, 28, 14, 44);
printf("\nMaximum of 43, 45, 65, 12, 32, 78, 9, 28, 14, 44 = %d", (int)max);
return (0);
} // main
% CC -o maximum maximum.c
% ./maximum
Maximum of 431, 276, 3982, 5, 54 = 3982
Maximum of 12.2, 1.3, 54.43 = 54.430000
Maximum of 43, 45, 65, 12, 32, 78, 9, 28, 14, 44 = 78
The caller knows the number of arguments pushed onto the stack, but the called routine maximum
does not, so it has to compute them at run-time. The va_start
macro computes the (saved frame pointer + offset) value following the argument past the last known argument (ie., const char* format)
). The rest of the arguments are then computed by calling va_arg
, where the argument to va_arg
is some (saved frame pointer + offset) value.
Reference:
Man page of va_start, va_arg, va_end