【问题标题】:Is it possible to have a variadic function in C with no non-variadic parameter?是否可以在 C 中使用没有非可变参数的可变参数函数?
【发布时间】:2010-04-12 12:51:05
【问题描述】:

我有以下功能:

void doStuff(int unusedParameter, ...)
{
    va_list params;
    va_start(params, unusedParameter);
    /* ... */
    va_end(params);
}

作为重构的一部分,我想删除未使用的参数,而不更改函数的实现。据我所知,当您没有最后一个非可变参数可供参考时,不可能使用va_start。有没有办法解决这个问题?

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

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

回应 cmets:我没有删除未使用的参数,但如果有一个干净的方法,我会这样做。我希望有一些我错过的简单的东西。

【问题讨论】:

  • @Axarydax:他特意问是否有其他解决方案。
  • 真的要删除吗?您可以将其视为第一个可变参数。
  • @Nick D:你应该让你的评论成为答案,你至少会得到我的一票。
  • "扫描 NULL" - 你说你想改变界面?例如,传递一个指向数组的指针 ;-)

标签: c variadic-functions


【解决方案1】:

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

#define doStuff(...) realDoStuff(0, __VA_ARGS__)

【讨论】:

  • 关于可变参数宏的文档链接在这里:gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html +1,你比我快几秒钟 :)
  • __VA_ARGS__ 是 C 语言 C99 标准的一部分。所以,它不是真正的“在 GCC 中”,而是“在现代 C 中”:)
  • VC++ 2005 及更高版本也支持,即使不支持 C99。
【解决方案2】:

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

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

无论哪种方式,重构接口以某种方式利用类型系统会更好 - 可能会重载使用的确切参数类型:

void doStuff( int );
void doStuff( const std::string& );
void doStuff( const MyFancyAppClass& );

希望这会有所帮助。

【讨论】:

  • 这是对的,但无效,这里的问题是针对 C 而不是 C++,您不能在 C 中重载函数并且创建数组可能代价高昂。如果更好的话,下面的答案。
  • 来自 OP:“……它实际上是一个 C++ 程序,……”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
相关资源
最近更新 更多