2014-03-28 42 views
0

我正在阅读文本Linux编程接口,它们显示此函数来处理错误。在手册页(man stdarg)中,它表示va_start必须首先调用以初始化ap以供va_arg()va_end使用。函数的可变参数是否需要va_start?

那么为什么在这个功能没有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 */ 
} 

回答

2

va_list ap被作为参数传递给函数outputError(),必须通过在va_startoutputError()呼叫者(呼叫者或呼叫者的等)进行初始化。

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

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

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