I am working on Advanced Programming in the UNIX Environment 3-Edition , and I find this code
err_msg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, 0, fmt, ap);
va_end(ap);
}
and err_doit is :
static void
err_doit(int errnoflag, int error, const char *fmt, va_list ap)
{
char buf[MAXLINE];
vsnprintf(buf, MAXLINE-1, fmt, ap);
if (errnoflag)
snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1, ": %s",
strerror(error));
strcat(buf, "\n");
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(NULL); /* flushes all stdio output streams */
}
What I didn't understand, is why the author passed a pointer to const char as an argument for va_start. As far as I know, you only allowed to pass the number of arguments represented by the ellipses section, as stated here:
void f1(int n, ...);
int f2(const char * s, int k, ...);
The rightmost parameter (the one just before the ellipses) plays a special role; the standard uses
the term parmN as a name to use in discussion. In the preceding examples, parmN would be n
for the first case and k for the second case. The actual argument passed to this parameter will
be the number of arguments represented by the ellipses section. source:
C Primer Plus by Stephen Prata.
Also I checked the two examples written in ISO C Standard: 7.15 Variable arguments and I found out that they pass too an int variable to va_start macro.
I am afraid that It's me who missed a point somewhere. I hope someone informs me.
The second argument to va_start is the last "real" argument, before the var-args arguments begin.
The err_msg() function only has a single normal argument, the const char *fmt pointer, so then clearly that is the last argument before the var-args part and should be passed to va_start().
The manual page says:
The argument last is the name of the last argument before the variable argument list, that is, the last argument of which the calling function knows the type.
The actual type of the second argument to va_list doesn't matter.
Also note that the quite common printf() function very probably does exactly this, as it too only has a single "ordinary" argument, the format string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With