头文件中是否需要包含stdarg.h来支持C语言可变参数?

4
#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库以支持...参数,或者是可选的?


1
声明类型/函数/对象需要头文件。... 不是这些,它是一个语法元素。 - Eugene Sh.
2个回答

6
标头不需要包括 <stdarg.h>,如果原型只包含省略号 (, ...) 表示法。实现 test() 函数的代码将需要包括 <stdarg.h>,但是声明它的标头则不需要。

然而,通常应该考虑创建第二个函数 void vtest(const char *format, va_list args);来匹配标头中的 test() 函数,此时你需要使用 <stdarg.h> 来定义 va_list 类型(实现代码不再需要单独的 #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()函数 —— 因为你很可能最终会需要它提供的额外灵活性。

0

不需要,但是如果没有这个头文件中的宏定义,访问隐藏在 ... 后面的参数会比较困难。

你需要了解你所使用的实现方式,例如对于 gcc,你可以使用以下方法:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接