C预处理器宏链
C preprocesor macro chain
下面有演示代码。我希望结果将被初始化数组。
#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 },
.
下一步是重新扫描并进一步替换(发生字符串化和粘贴后,其中有none)。在这个阶段,剩余的标记被重新扫描,以便宏可以扩展(在蓝色绘制当前宏之后,但这在这里没有效果)。在此阶段,_NAME
被识别为类对象宏,因此开始扩展。这恰好扩展为 name
,但我们已经完成了参数替换,因此此时它与 参数 name
没有任何关系......它是只是另一个标记。
下面有演示代码。我希望结果将被初始化数组。
#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 },
.
下一步是重新扫描并进一步替换(发生字符串化和粘贴后,其中有none)。在这个阶段,剩余的标记被重新扫描,以便宏可以扩展(在蓝色绘制当前宏之后,但这在这里没有效果)。在此阶段,_NAME
被识别为类对象宏,因此开始扩展。这恰好扩展为 name
,但我们已经完成了参数替换,因此此时它与 参数 name
没有任何关系......它是只是另一个标记。