使用指向const char的指针作为va_start的第二个参数

ISl*_*ani 2 c unix pointers

我正在UNIX环境3版中进行高级编程,我找到了这段代码

err_msg(const char *fmt, ...)
{
    va_list     ap;

    va_start(ap, fmt);
    err_doit(0, 0, fmt, ap);
    va_end(ap);
} 
Run Code Online (Sandbox Code Playgroud)

err_doit是:

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 */
}
Run Code Online (Sandbox Code Playgroud)

我不明白的是,为什么作者传递指针const char作为参数va_start.据我所知,你只允许传递省略号部分所代表的参数数量,如下所述:

void f1(int n, ...);
int f2(const char * s, int k, ...);
Run Code Online (Sandbox Code Playgroud)

最右边的参数(省略号之前的参数)起着特殊的作用; 该标准使用该术语parmN作为名称用于讨论.在前面的例子中,parmN n 用于第一种情况,k第二种情况用于第二种情况.传递给此参数的实际参数将是省略号部分表示的参数数.来源:Stephen Prata的C Primer Plus.

我还检查了用ISO C标准编写的两个例子:7.15变量参数 ,我发现它们也将int变量传递给va_start宏.

我担心我错过了某个地方.我希望有人告诉我.

unw*_*ind 5

第二个参数va_start是var-args参数开始之前的最后一个"真实"参数.

err_msg() 函数只有一个普通参数,即const char *fmt指针,因此很明显这是var-args部分之前的最后一个参数,应该传递给它va_start().

手册页说:

参数last是变量参数列表之前的最后一个参数的名称,也就是调用函数知道类型的最后一个参数.

第二个参数的实际类型va_list无关紧要.

还要注意,相当普遍的printf()功能很可能就是这样,因为它也只有一个"普通"参数,即格式字符串.