头文件中的“...”参数是否需要包含 stdarg.h?

Is including stdarg.h necessary for "..." argument in header files?

#ifndef WHATEVER_H
#define WHATEVER_H

void test(const char *format, ...); // would you have to #include <stdarg.h> for ... on argument, or is it ok if you don't use it

#endif // WHATEVER_H

所以如果我有一个像这样的头文件,我需要把 ... 作为我的 void test 函数的参数,我是否必须包含 stdarg.h ... 参数,或者它不是强制性的?

如果原型只包含省略号 (, ...),则 header 不需要包含 <stdarg.h>。实现 test() 函数的代码需要包含 <stdarg.h>,但声明它的 header 不需要。

但是,你应该经常考虑创建第二个函数,void vtest(const char *format, va_list args);来匹配header中的test()函数,然后你确实需要<stdarg.h>来定义va_list 类型(实现代码不再需要单独的 #include <stdarg.h>)。在 header 中使用 vtest() 声明,test() 函数的实现变得微不足道:

void test(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    vtest(format, args);
    va_end(args);
}

这特别简单,因为没有 return 值可以传递,但是 return 传递一个值并不难。使用此方案实现像 test() 这样的可变参数函数通常是个好主意,即使您不公开 vtest() 函数——您很可能会想要它最终提供的额外灵活性.

不,你不需要,但是如果没有这个 header.

的宏,将很难访问隐藏在 ... 后面的参数

您需要了解您的实现,例如您可以使用的 gcc:

__builtin_va_start(v,l)
__builtin_va_end(v)
__builtin_va_arg(v,l)
__builtin_va_copy(d,s)