Q: I have a pre-ANSI compiler, without <stdarg.h>. What can I do?
A: There's an older header, <varargs.h>, which offers about the same functionality.
Here is the vstrcat function from question 15.4, rewritten to use <varargs.h>:
#include <stdio.h> #include <varargs.h> #include <string.h> extern char *malloc(); char *vstrcat(va_alist) va_dcl /* no semicolon */ { int len = 0; char *retbuf; va_list argp; char *p; va_start(argp); while((p = va_arg(argp, char *)) != NULL) /* includes first */ len += strlen(p); va_end(argp); retbuf = malloc(len + 1); /* +1 for trailing \0 */ if(retbuf == NULL) return NULL; /* error */ retbuf[0] = '\0'; va_start(argp); /* restart for second scan */ while((p = va_arg(argp, char *)) != NULL) /* includes first */ strcat(retbuf, p); va_end(argp); return retbuf; }(Note that there is no semicolon after va_dcl. Note that in this case, no special treatment for the first argument is necessary.) You may also have to declare the string functions by hand rather than using <string.h>.
If you can manage to find a system with vfprintf but without <stdarg.h>, here is a version of the error function (from question 15.5) using <varargs.h>:
#include <stdio.h> #include <varargs.h> void error(va_alist) va_dcl /* no semicolon */ { char *fmt; va_list argp; fprintf(stderr, "error: "); va_start(argp); fmt = va_arg(argp, char *); vfprintf(stderr, fmt, argp); va_end(argp); fprintf(stderr, "\n"); }(Note that in contrast to <stdarg.h>, under <varargs.h> all arguments are variable, so the fmt argument must also be picked up via va_arg.)
References:
H&S Sec. 11.4 pp. 296-9
CT&P Sec. A.2 pp. 134-139
PCS Sec. 11 pp. 184-5, Sec. 13 p. 250