我正在阅读Linux编程接口文本并显示此功能来处理错误。在手册页(man stdarg
)中,必须首先调用va_start
来初始化ap
以供va_arg()
和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 */
}
答案 0 :(得分:2)
va_list ap
作为参数传递给函数outputError()
,它必须在va_start
(或调用者的调用者等)的调用者中由outputError()
初始化。< / p>
要回答您的主要问题,是的,va_start
是必需的,但不一定在当前使用vp_list
的函数中。 va_end
也一样。
答案 1 :(得分: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;
}
我认为这清楚地回答了你的问题。