Open
Description
记录一个 GCC Clang 可变参数宏展开问题
当使用可变参数宏时,如下:
#define test_macro(len, ...) test_func(len, __VA_ARGS__)
test_macro(1, 1);
test_macro(2, 1, 2);
macOS 可以使用如下命令查看宏展开后的结果:
cc -E test.c -o test.txt
可以看到展开结果如下:
test_func(1, 1);
test_func(2, 1, 2);
没有问题,但是当这样使用的时候,就会有问题了:
test_func(0);
可以看到展开成了
test_func(0, );
这里有明显的语法错误
不过这个问题可以通过,下面的方式解决
#define test_macro(len, ...) test_func(len, ##__VA_ARGS__)
通过添加##
,再展开的内容就正确了:
test_func(0);
但是,这样依旧会遇到一个问题:
test_macro(1, test_macro(1, 1));
当我嵌套使用宏的时候,展开结果就有问题了:
test_func(1, test_macro(1, 1));
可以看到,只有外层的test_macro
展开了,参数没有展开,因此,这时候编译就会有如下报错:
test.c:9:19: warning: implicit declaration of function 'test_macro' is invalid in C99
[-Wimplicit-function-declaration]
test_macro(1, test_macro(1, 1));
^
1 warning generated.
Undefined symbols for architecture x86_64:
"_test_macro", referenced from:
_main in test-77cf0d.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
这个问题可以通过下面的写法解决:
#define _test_macro(len, ...) test_func(len, ##__VA_ARGS__)
#define test_macro(len...) _test_macro(len)
此时再查看展开的内容就正确了:
test_func(1, test_func(1, 1));