Skip to content

记录一个 GCC Clang 可变参数宏展开问题 #6

Open
@yangruihan

Description

@yangruihan

记录一个 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));

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions