Search code examples
cvariadic-functionsvariadic-macros

Is va_start required in variadic arguments for functions?


I'm reading the text The Linux Programming Interface and they show this function to handle errors. In the man pages (man stdarg) it says va_start must be called first to initialize ap for use by va_arg() and va_end.

So why in this function there is no va_start?

static void
outputError(Boolean useErr, int err, Boolean flushStdout,
        const char *format, va_list ap) 
{
#define BUF_SIZE 500
    char buf[BUF_SIZE], userMsg[BUF_SIZE], errText[BUF_SIZE];

    vsnprintf(userMsg, BUF_SIZE, format, ap);

    if (useErr)                                                                               
        snprintf(errText, BUF_SIZE, " [%s %s]",
                (err > 0 && err <= MAX_ENAME) ?
                ename[err] : "?UNKNOWN?", strerror(err));
    else
        snprintf(errText, BUF_SIZE, ":");

    snprintf(buf, BUF_SIZE, "ERROR%s %s\n", errText, userMsg);

    if (flushStdout)
        fflush(stdout);       /* Flush any pending stdout */
    fputs(buf, stderr);
    fflush(stderr);           /* In case stderr is not line-buffered */
}

Solution

  • va_list ap is passed as argument to the function outputError(), it must be initialized by va_start in the caller of outputError() (or caller of caller, etc).

    To answer your main question, yes, va_start is required, but not necessarily in the current function where vp_list is used. The same for va_end.