Question

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 */
}
Was it helpful?

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.

OTHER TIPS

So why in this function there is no va_start?

Here is one of the places that outputError() is used:

void
errMsg(const char *format, ...)
{
    va_list argList;
    int savedErrno;
    savedErrno = errno;
    /* In case we change it here */
    va_start(argList, format);
    outputError(TRUE, errno, TRUE, format, argList);
    va_end(argList);
    errno = savedErrno;
}

I think this answered your question clearly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top