Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a pointer to const char as a second argument for va_start

Tags:

c

unix

pointers

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.

like image 313
ISlimani Avatar asked Feb 26 '26 04:02

ISlimani


1 Answers

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.

like image 191
unwind Avatar answered Feb 28 '26 19:02

unwind



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!