目录
1.知识回顾
之前在以下文章讲过宏的基本概念:
但如果读者有去看一些开源项目的话,会发现有使用可变参数宏的,本文来讲讲
2.可变参数宏
gcc文档有介绍Variadic Macros - The C Preprocessor,这里提几个要点
可变参数必须放在所有有名参数的后面
比如这个宏的可变参数用"..."表示,放在有名参数a、b、c的后面:
cpp
#define foo(a, b, c, ...) xxxxxxx
VA_ARGS
cpp
#include <stdio.h>
#define TEST_VARIABLE_ARGS(a,b,c,...) printf(__VA_ARGS__)
int main()
{
TEST_VARIABLE_ARGS(1, 2, 3, "%c,%f,%s", 'a', 2.5, "ccc");
return 0;
}
__VA_ARGS__相当于可变参数的占位符,比如上方代码的test_variable_args(1, 2, 3, "%c,%f,%s", 'a', 2.5, "ccc")进行宏替换后的结果就是:
cpp
printf("%c,%f,%s", 'a', 2.5, "ccc");
运行结果:

如果可变参数可能为空,可能不为空,可以使用##来处理:
cpp
#include <stdio.h>
// 可变参数宏:当 __VA_ARGS__ 为空时,##会删除前面的逗号
#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__)
int main() {
// 情况1:有可变参数,##不起删除作用
FOO("Hello, %s!\n", "Alice");
// 展开为:printf("Hello, %s!\n", "Alice");
// 情况2:可变参数为空,##删除前面的逗号
FOO("Hello, world!\n");
return 0;
}
预处理后的结果:
cpp
int main() {
printf("Hello, %s!\n", "Alice");
printf("Hello, world!\n");
return 0;
}
运行结果:
