2

我正在阅读 Linux 编程接口文本,他们展示了这个函数来处理错误。在手册页(man stdarg)中,它说va_start必须首先调用以进行初始化ap以供va_arg()and使用va_end

那么为什么在这个函数中没有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 */
}
4

2 回答 2

3

va_list ap作为参数传递给函数outputError(),它必须va_start在调用者outputError()(或调用者的调用者等)中初始化。

要回答您的主要问题,是的,va_start是必需的,但不一定在当前vp_list使用的功能中。对于va_end.

于 2014-03-28T03:41:37.250 回答
1

那么为什么在这个函数中没有va_start

这是outputError()使用的地方之一:

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;
}

我认为这清楚地回答了你的问题。

于 2014-03-28T03:41:12.410 回答