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

问题描述

#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函数的参数,我是否必须为{{1 }}的论点,还是不是必须的?

解决方法

如果原型仅包含省略号(<stdarg.h>),则标头不必包含,...。实现test()函数的代码将需要包含<stdarg.h>,但是标头中声明不需要。

但是,您通常应该考虑创建第二个函数void vtest(const char *format,va_list args);以匹配标题中的test()函数,然后您确实需要<stdarg.h>来定义va_list typen(并且实现代码不再需要单独的#include <stdarg.h>)。在标头中使用vtest()声明后,test()函数的实现变得很简单:

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

这特别简单,因为没有中继的返回值,但是返回值并不难。即使您不公开test()函数,使用这种方案实现像vtest()这样的可变函数通常也是个好主意-最终您可能会希望它提供额外的灵活性

,

不需要,但是如果没有此标头中的宏,将很难访问...后面隐藏的参数。

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

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