[英]How to define a C macro that uses another macro?
我有以下场景......
Header 文件:
#define TRIG_INDEX 200
#define PATH(target_p) some.path.to.target##target_p
源文件:
read_from_target(PATH(TRIG_INDEX));
由于PATH
宏将target_p
附加到最后的文本中,因此编译失败,因为some.path.to.targetTRIG_INDEX
不是有效路径。
我期待在上述情况下得到read_from_target(some.path.to.target200)
。
我如何(如果有的话)定义宏来接受这种情况?
参数必须由宏扩展:
#define TRIG_INDEX 200
#define PATH_TARGET(x) some.path.to.target##x
#define PATH(target_p) PATH_TARGET(target_p)
类似函数的宏的预处理器宏扩展/替换规则相当复杂。 基本上它按以下顺序执行:
宏名称后面的东西称为替换列表。 在这种情况下PATH_TARGET(target_p)
- PATH
应该被替换的东西。
##
或#
与宏参数一起出现意味着该参数被其相应的预处理器标记序列(如果适用)替换。 在这种情况下,参数target_p
被替换为TRIG_INDEX
,因此我们得到some.path.to.target##TRIG_INDEX
创建新的预处理器令牌some.path.to.targetTRIG_INDEX
,这与预期不符。
其他宏参数得到扩展。 不适用于这里。
然后重新扫描替换列表以查找要扩展的宏名称,但为时已晚,因为已经发生了与##
的预处理器标记连接。
上面的“其他宏参数得到扩展”部分对于解决问题很有用。 因此替换列表中的宏参数优先于宏名称。 我们可以通过添加一个辅助宏来利用这一点:
#define TRIG_INDEX 200
#define EXPAND(tgt) some.path.to.target##tgt
#define PATH(target_p) EXPAND(target_p)
现在在PATH
的替换列表的扩展中,我们首先得到宏参数扩展: taget_p
被替换,我们得到EXPAND(TRIG_INDEX)
。 然后重新扫描替换列表以查找要替换的宏名称,预处理器找到两个这样的宏名称: EXPAND
和TRIG_INDEX
。 两者都被扩展,因此TRIG_INDEX
被替换为200
。 然后EXPAND
根据相同的规则递归扩展( ##
强制将该宏参数tgt
扩展为200
,然后再进行其他任何操作)。
有关详细信息,请参阅 C17 标准第 6.10.3 章 - 这一章也是指定 # 和 ## 运算符的行为的一章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.