问题描述
#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)