varargs(5) File Formats Manual varargs(5)
varargs - handle variable argument list
This set of macros enables programmers to write portable procedures that accept variable argument lists. Routines that have variable argu-
ment lists (such as but do not use are inherently nonportable, because different machines use different argument-passing conventions (see
is used as the parameter list in a function header.
is a declaration for No semicolon should follow
is a type defined for the variable used to traverse the list.
is called to initialize pvar to the beginning of the list. The type of argN should be the same as the argument to the function just before
the variable portion of the argument list.
returns the next argument in the list pointed to by type is the type the argument is expected to be. Different types can be mixed, but it
is up to the routine to know what type of argument is expected, because it cannot be determined at runtime.
is used to clean up.
Multiple traversals, each bracketed by are possible.
NOTE: The header file is provided for compatibility with pre-ANSI compilers and earlier releases of HP C/HP-UX. It is superceded by which
includes all of the macros.
The following example shows a possible implementation of (see exec(2)):
The next example illustrates how a function that receives variable arguments can pass these arguments down to other functions. To accom-
plish this, the first routine in this example) which receives the variable argument list must pass the address pointer resulting from a
call to on to any subsequent calls that need to access this same variable argument list. All routines that receive this address pointer in
this example) need only to use to access the original variable argument list just as if they were the original routine to be passed the
In this example, one can imagine that there are a series of other routines (such as a and that also call the function.
/* VARARGS4 -- for lint */
log_errors(log_fp, func_name, err_num, msg_fmt, va_alist)
/* Print error header information */
(void) fprintf(log_fp, "
ERROR in process %d
(void) fprintf(log_fp, " function "%s": ", func_name);
(void) fprintf(log_fp, "illegal option
(void) fprintf(log_fp, "cannot parse input file
* Get pointer to first variable argument so that we can
* pass it on to v_print_log(). We do this so that
* v_print_log() can access the variable arguments passed
* to this routine.
v_print_log(log_fp, msg_fmt, ap);
/* VARARGS2 -- for lint */
v_print_log(log_fp, fmt, ap)
* If "%Y" is the first two characters in the format string,
* a second file pointer has been passed in to print general
* message information to. The rest of the format string is
* a standard printf(3S) format string.
if ((*fmt == '%') && (*(fmt + 1) == 'Y'))
fmt += 2;
other_fp = (FILE *) va_arg(ap, char *);
if (other_fp != (FILE *) NULL)
* Print general message information to additional stream.
(void) vfprintf(other_fp, fmt, ap);
* Now print it to the log file.
(void) vfprintf(log_fp, fmt, ap);
It is up to the calling routine to specify how many arguments there are, because it is not always possible to determine this from the stack
frame. For example, is passed a zero pointer to signal the end of the list. can determine how many arguments are present by the format.
It is non-portable to specify a second argument of or to because arguments seen by the called function are not or C converts and arguments
to and converts arguments to before passing them to a function.
exec(2), vprintf(3S), stdarg(5).