c - 为什么 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)中找不到任何关于花括号被特殊处理的内容。
为什么会这样?
解决方案
原因是调用被逗号分隔以查找参数,忽略任何字符,例如 { 和 }(参见下面的标准引用)。只有常规的括号会受到特殊处理。
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)行为未定义。
推荐阅读
- javascript - 我无法在我的 Laravel 项目中管理我的布局
- kubernetes - [ERROR KubeletVersion]:kubelet 版本高于控制平面版本
- inno-setup - 在 Inno Setup 中更改任务列表框和其他控件的背景颜色
- android - Android:JSONDownloader 返回空字符串
- ios - 更改在 TestFlight 上使用但不是 App Store 的应用程序的捆绑包 ID
- javascript - 在数组对象内过滤数组后返回值
- ios - Xcode 10 自动完成功能在其他 swift 文件中不起作用
- zend-framework - Swoole http 服务器中的 Zend View 行为
- qt - 如何实时可视化来自不同线程的图像?
- android - Progressive Web App - 迄今为止所有可用的权限