假设我有一个C函数,它有一个可变数量的参数:我如何调用另一个函数,它期望从它内部有一个可变数量的参数,传递进入第一个函数的所有参数?
例子:
void format_string(char *fmt, ...);
void debug_print(int dbg_lvl, char *fmt, ...) {
format_string(fmt, /* how do I pass all the arguments from '...'? */);
fprintf(stdout, fmt);
}
假设你写了一个典型的变进函数。因为在可变参数之前至少需要一个参数…,你必须总是在使用中写一个额外的参数。
还是你呢?
如果将可变参数函数包装在宏中,则不需要前面的参数。想想这个例子:
#define LOGI(...)
((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
这显然要方便得多,因为您不需要每次都指定初始参数。
为了传递省略号,像往常一样初始化一个va_list,然后简单地将它传递给第二个函数。你不使用va_arg()。特别地;
void format_string(char *fmt,va_list argptr, char *formatted_string);
void debug_print(int dbg_lvl, char *fmt, ...)
{
char formatted_string[MAX_FMT_SIZE];
va_list argptr;
va_start(argptr,fmt);
format_string(fmt, argptr, formatted_string);
va_end(argptr);
fprintf(stdout, "%s",formatted_string);
}
罗斯的解决方案清理了一点。只有当所有参数都是指针时才有效。此外,如果__VA_ARGS__为空,语言实现必须支持省略前面的逗号(Visual Studio c++和GCC都支持)。
// pass number of arguments version
#define callVardicMethodSafely(...) {value_t *args[] = {NULL, __VA_ARGS__}; _actualFunction(args+1,sizeof(args) / sizeof(*args) - 1);}
// NULL terminated array version
#define callVardicMethodSafely(...) {value_t *args[] = {NULL, __VA_ARGS__, NULL}; _actualFunction(args+1);}