c-preprocessor - C 预处理器宏链
问题描述
我在下面有演示代码。我希望结果将是初始化数组。
#define _NAME name
#define CFIT(name)\
{ _NAME },
const char * idns[] = {
CFIT("address")
CFIT("device_id")
CFIT("device_bh")
CFIT("device_hw")
CFIT("device_fw")
"" };
...但是预处理器创建了这个:
const char * idns[] = {
{ name },
{ name },
{ name },
{ name },
{ name },
""
};
令人惊讶的是,C++ 预处理器按预期工作。用 'name' 标记替换 _NAME 宏也可以直接使用。有什么提示吗?使用 32b mingw 5.3.0。
解决方案
让我们只看一个调用;我会选择这个:
CFIT("address")
预处理器首先执行参数替换。在此阶段,如果参数 ( name
) 在替换列表中 ( { _NAME },
; 我只是在此处去除空格),并且没有被字符串化或参与粘贴,则参数将完全展开,结果将替换为参数。在这里,name
没有出现在那个替换列表中,所以没有什么可做的。所以在参数替换之后,你有{ _NAME },
.
下一步是重新扫描和进一步替换(在字符串化和粘贴发生之后,其中没有)。在这个阶段,剩余的标记被重新扫描,以便宏可以扩展(在蓝色绘制当前宏之后,但这在这里没有效果)。在此阶段,_NAME
被识别为类对象宏,因此开始扩展。这恰好扩展为,但我们已经完成了参数替换,因此此时它与参数name
无关......它只是另一个标记。 name
推荐阅读
- c++ - 清除向量中的重复对象会产生无限循环
- angularjs - 如何让窗口滚动功能在Angularjs中工作
- debugging - 调试 ARM Cortex-M4 中的硬故障
- swift - 如何在 Swift 中扩展 String.Iterator
- r - 梯形图 if else 中每个都有多个语句
- ruby-on-rails - 在 Rails 中限制每个用户的后台工作人员数量
- java - 如何将四个图像中的一个随机分配给一个字段
- kubernetes - Kubernetes:自定义 Pod 调度和 Volume 调度
- javascript - React,根据父组件和两个子组件之间的通信有条件地渲染组件
- c# - 使用 terminal.gui 时 C# 找不到对象引用