【问题标题】:Why does a C macro invocation eat up curly braces?为什么 C 宏调用会占用大括号?
【发布时间】:2019-03-27 12:12:42
【问题描述】:

考虑:

#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});

clang 3.8.1:

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

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

为什么会这样?

【问题讨论】:

标签: c c-preprocessor


【解决方案1】:

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

所以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 节:

由最外面的匹配括号限制的预处理标记序列 形成类函数宏的参数列表。内的个别论点 该列表由逗号预处理标记分​​隔,但逗号预处理标记 匹配的内括号之间不分隔参数。如果有序列 预处理参数列表中的标记,否则这些标记将充当 预处理指令,172) 行为未定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-21
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多