C语言如何将函数可变参数(...)直接传递给另一函数而不使用va_list
C语言可变参数透传解决方案
标准C语法本身不支持直接将一个可变参数函数的...参数原封不动传递给另一个可变参数函数,你示例中oof(stdout, fmt, ...);的写法不符合C语法规范,无法通过编译。
如果你要求不修改oof的现有定义、不传递va_list类型参数给oof,最常用的实现方式是将foo从函数改为可变参数宏,示例代码如下:
#include <stdio.h> #include <stdarg.h> void oof(FILE * f, const char * fmt, ...){ va_list args; va_start(args, fmt); vfprintf(f, fmt, args); va_end(args); } // ##__VA_ARGS__为编译器通用扩展,处理没有可变参数传入的边界情况 #define foo(fmt, ...) do { \ oof(stdout, fmt, ##__VA_ARGS__); \ // 原foo函数内的其他逻辑可直接写在此处 } while(0) int main(int argc, char *argv[]){ foo("Hello %s\n", "World"); // 支持无额外参数的调用场景 foo("Test output without args\n"); }
该方案的优势是完全满足你的要求,不需要调整oof的任何代码,对外调用方式和原函数版本的foo完全一致;劣势是宏没有编译期类型检查,复杂逻辑写在宏中可读性、调试便利性都会下降。
如果可以接受对oof的内部实现做少量调整(对外接口保持不变),更规范的工业界实现是新增va_list版本的内部实现,示例代码如下:
#include <stdio.h> #include <stdarg.h> // 新增内部va_list版本实现,对外不暴露即可 static void voof(FILE * f, const char * fmt, va_list args){ vfprintf(f, fmt, args); } // 原有oof对外接口完全不变,不影响其他调用位置的代码 void oof(FILE * f, const char * fmt, ...){ va_list args; va_start(args, fmt); voof(f, fmt, args); va_end(args); } void foo(const char * fmt, ...){ va_list args; va_start(args, fmt); voof(stdout, fmt, args); va_end(args); // 其他逻辑正常编写即可 } int main(int argc, char *argv[]){ foo("Hello %s\n", "World"); }
该方案的优势是类型安全,调试方便,适合foo内部逻辑复杂的场景,同时完全不影响现有oof的对外使用。
内容的提问来源于stack exchange,提问作者dsal3389
相关产品推荐
相关产品推荐

