stdarg vs. varargs

Rather than conflict with the historical routines in <varargs.h>, the International Standards Organization/American Standards Institute (ISO/ANSI) C standard defines a new mechanism for dealing with variable argument lists, <stdarg.h>. The varargs mechanism uses a magic name (va_alist) for the first argument in a list; stdarg uses the last required argument. This means that stdarg must have at least one named parameter. The Interix Software Development Kit (SDK) ships both headers, so you need not convert from one to the other. If you want ANSI standard code, you should convert from varargs to stdarg.

Usually, you can translate from varargs to stdarg easily, because most functions with variable argument lists have a known first-argument type. The following example is a trivial, error-printing function that uses the varargs mechanism:

#include <varargs.h>
printerror( va_alist );

void printerror (va_alist )
va_dcl
{
   va_list ap;
   char *fmt;
   va_start(ap);
   fmt = va_arg(ap, char *);
   vprintf(stderr, fmt, ap);
   va_end(ap);
}

Because the function uses a format string as its first argument, you can easily use it as the known argument:

#include <stdarg.h>
void printerror (char *fmt, ...)
{
   va_start(ap, fmt);
   vfprintf(stderr, fmt, ap);
   va_end(ap);
}

You must give the first argument a name, even when the routine takes a terminated list and no fixed arguments. For example, the following function prints a set of strings, but the first argument is entirely artificial, created to meet the needs of the stdarg package:

#include <stdarg.h>
pr_str(char *first, ...)
{
   char * current;
   va_list argp;
   va_start(argp,first);
   current = first;
   while (current != NULL){
   fputs(current,stdout);
   current = va_arg(argp, char *);
   }
   va_end(argp);
}