是否可以在C中具有可变参数函数且没有非可变参数?

Tim*_*tin 16 c variadic-functions

我有以下功能:

void doStuff(int unusedParameter, ...)
{
    va_list params;
    va_start(params, unusedParameter);
    /* ... */
    va_end(params);
}
Run Code Online (Sandbox Code Playgroud)

作为重构的一部分,我想删除未使用的参数,而不另行更改函数的实现.据我所知,va_start当你没有最后一个非变量参数引用时,就不可能使用它.有没有办法解决?

背景:它实际上是一个C++程序,所以我可以使用这里建议的一些运算符重载魔法,但我希望此时不必更改接口.

现有函数通过要求变量参数列表以空值终止并扫描NULL来完成其工作,因此它不需要一个前导参数来告诉它有多少参数.

在回应评论:我不具备删除未使用的参数,但我会做到这一点,如果有一个干净的方式来做到这一点.我希望有一些我想念的简单.

Aar*_*lla 14

在GCC中,您有一个解决方法:您可以定义具有可变数量参数的宏,然后在扩展中添加虚拟参数:

#define doStuff(...) realDoStuff(0, __VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)

  • `__VA_ARGS__`是C语言C99标准的一部分.所以,它不是真的"在GCC"而是"在现代C":) (8认同)

Nik*_*sov 3

您的选择是要么保持原样并使用va_list, 别名它(如果它是 GCC),就像其他人指出的那样,或者按照接口的方式做一些事情exec(2)- 传递需要终止符的指针数组NULL

/* \param args  NULL-terminated array of
 *              pointers to arguments.
 */
void doStuff( void* args[] );
Run Code Online (Sandbox Code Playgroud)

不管怎样,重构接口以某种方式利用类型系统会更好——可能会重载所使用的确切参数类型:

void doStuff( int );
void doStuff( const std::string& );
void doStuff( const MyFancyAppClass& );
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

  • 这是正确的,但无效,这里的问题是针对 C 而不是 C++,你不能重载 C 中的函数,并且创建数组可能会很昂贵。下面的答案如果更好的话。 (2认同)