为什么 C 宏调用会耗尽大括号?

Why does a C macro invocation eat up curly braces?

考虑:

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

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

相反,gcc 和 clang 都抱怨。海湾合作委员会 7.3.0:

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

clang 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) 中找不到任何提及花括号被特殊处理的内容。

为什么会这样?

原因是调用由逗号分隔以查找参数,忽略任何字符,例如 { 和 }(请参阅下面的标准引用)。仅对常规括号进行特殊处理。

所以 TEST({1, 2}) 被解释为传递了两个参数,{12}。 确实:

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

被预处理成:

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

第 6.10.3.11 节:

The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, 172) the behavior is undefined.