问题
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 */
}
回答1:
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
.
回答2:
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.
来源:https://stackoverflow.com/questions/22703657/is-va-start-required-in-variadic-arguments-for-functions