首页 > 解决方案 > 为什么 C 宏调用会占用大括号?

问题描述

考虑:

#define TEST(x) x
int arr[2] = TEST({1, 2});

我希望它被预处理成int arr[2] = {1, 2};

相反,gcc 和 clang 都抱怨。gcc 7.3.0:

./test.c:2:25: error: macro "TEST" passed 2 arguments, but takes just 1
 int arr[2] = TEST({1, 2});

铿锵3.8.1:

./test.c:2:23: error: too many arguments provided to function-like macro invocation
int arr[2] = TEST({1, 2});

我在宏的 C 语言标准部分(6.10)中找不到任何关于花括号被特殊处理的内容。

为什么会这样?

标签: cc-preprocessor

解决方案


原因是调用被逗号分隔以查找参数,忽略任何字符,例如 { 和 }(参见下面的标准引用)。只有常规的括号会受到特殊处理。

SoTEST({1, 2})被解释为传递了两个参数,{1并且2}. 确实:

#define TEST(x, y) | x | y |
int arr[2] = TEST({1, 2});

被预处理成:

int arr[2] = | {1 | 2} |;

第 6.10.3.11 节:

由最外面的匹配括号界定的预处理标记序列形成了类函数宏的参数列表。列表中的各个参数由逗号预处理标记分​​隔,但匹配内括号之间的逗号预处理标记不分隔参数。如果在参数列表中存在预处理标记序列,否则它们将充当预处理指令,172)行为未定义。


推荐阅读