C语言 如何在 C 函数中使用 __VA_ARGS__ 而不是宏?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4339412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use __VA_ARGS__ inside a C function instead of macro?
提问by Jona
Possible Duplicate:
C/C++: Passing variable number of arguments around
可能的重复:
C/C++:传递可变数量的参数
I'm currently using the following macro declared on my C file.
我目前正在使用在我的 C 文件中声明的以下宏。
#define COMMON_Print(...) printf (__VA_ARGS__)
Now that call works just fine, but turns out that I need to be able to create a C function that looks something like this:
现在该调用工作正常,但事实证明我需要能够创建一个看起来像这样的 C 函数:
void COMMON_Print(...)
{
printf (__VA_ARGS__);
}
So that function doesn't work, I get an error
所以该功能不起作用,我收到一个错误
"Error : undefined identifier __VA_ARGS__"
“错误:未定义标识符 __VA_ARGS__”
The complexity of my project requires to have a function since it's an interface... So how can I get the parameters ... and pass them to the printf function? Or better what am I doing wrong?
我的项目的复杂性需要有一个函数,因为它是一个接口......那么我如何获取参数......并将它们传递给 printf 函数?或者更好的是我做错了什么?
Thanks!
谢谢!
回答by John Kugelman
Each of the ?printffunctions has a corresponding v?printffunction which does the same thing but takes a va_list, a variable argument list.
每个?printf函数都有一个相应的v?printf函数,它做同样的事情,但需要一个va_list,一个可变参数列表。
#include <stdio.h>
#include <stdarg.h>
void COMMON_Print(char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
Side note:Notice that va_starttakes the name of the last argument before the ...as a parameter. va_startis a macro which does some stack-based magic to retrieve the variable arguments and it needs the address of the last fixed argument to do this.
旁注:请注意,va_start将 the 之前的最后一个参数的名称...作为参数。va_start是一个宏,它执行一些基于堆栈的魔法来检索变量参数,它需要最后一个固定参数的地址来执行此操作。
As a consequence of this, there has to be at least one fixed argument so you can pass it to va_start. This is why I added the formatargument instead of sticking with the simpler COMMON_Print(...)declaration.
因此,必须至少有一个固定参数,以便您可以将其传递给va_start. 这就是我添加format参数而不是坚持使用更简单的COMMON_Print(...)声明的原因。
See:http://www.cplusplus.com/reference/clibrary/cstdio/vprintf/
参见:http : //www.cplusplus.com/reference/clibrary/cstdio/vprintf/
回答by Michael Mrozek
__VA_ARGS__is only for macros; variadic functions are rather different. You need to use va_start, va_argand va_endfrom stdarg.hto handle them.
__VA_ARGS__仅适用于宏;可变参数函数相当不同。您需要使用va_start,va_arg和va_endfromstdarg.h来处理它们。
First, your function needs at least one named parameter, e.g.:
首先,您的函数至少需要一个命名参数,例如:
void COMMON_Print(const char* fmt, ...)
Then you can define a va_listand use va_startto set it:
然后你可以定义一个va_list并使用va_start来设置它:
va_list args;
va_start(args, fmt);
// your code here
va_end(args);
Now you can use argsto access the arguments; calling va_arg(args, TYPE)will return the next variadic argument, so you can just keep calling that until you've read all the arguments.
现在您可以使用args来访问参数;调用va_arg(args, TYPE)将返回下一个可变参数,因此您可以继续调用它,直到您阅读所有参数。
If you're just trying to call printf, there's a printf variant called vprintfthat takes the va_listdirectly:
如果你只是想呼吁printf,有一个名为printf的变种vprintf,是以va_list直接:
vprintf(fmt, args);
There is no easy way to call one variadic function from another; you need something like vprintfthat takes the whole va_list
没有简单的方法可以从另一个调用一个可变参数函数;你需要的东西一样vprintf,是以整va_list
回答by nos
__VA_ARGS__is for macros only.
__VA_ARGS__仅适用于宏。
Chaining the variable number of argument to another function can't be done directly. Instead you have to pass a va_list , and the function you're calling have to take a va_list. Luckily there's a variation of printf that does this, your function have to be written this way:
不能直接将可变数量的参数链接到另一个函数。相反,您必须传递 va_list ,并且您调用的函数必须采用 va_list。幸运的是, printf 有一个变体可以做到这一点,你的函数必须这样写:
void COMMON_Print(char *format,...)
{
va_list args;
va_begin(args,format);
vsprintf(format,args);
va_end(args);
}

