繁体   English   中英

如何定义使用另一个宏的 C 宏?

[英]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) 然后重新扫描替换列表以查找要替换的宏名称,预处理器找到两个这样的宏名称: EXPANDTRIG_INDEX 两者都被扩展,因此TRIG_INDEX被替换为200 然后EXPAND根据相同的规则递归扩展( ##强制将该宏参数tgt扩展为200 ,然后再进行其他任何操作)。

有关详细信息,请参阅 C17 标准第 6.10.3 章 - 这一章也是指定 # 和 ## 运算符的行为的一章。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM