在 C 中的宏中替换宏

Posted

技术标签:

【中文标题】在 C 中的宏中替换宏【英文标题】:Substituting macros within macros in C 【发布时间】:2016-10-11 19:46:25 【问题描述】:

我正在尝试使代码部分可重用。我在下面的评论 sn-p 没有做我想做的事:

#define NAME ABC 
#define LOG_SIZE NAME##_LEN 

我希望 LOG_SIZE 解析为 ABC_LEN。我试过玩弄#'s,但无法让它工作。整个代码都使用LOG_SIZE,所以我不想把宏改成:

#define LOG_SIZE(name) name##_LEN

有没有办法做到这一点?

【问题讨论】:

【参考方案1】:

问题在于,如果宏参数被字符串化或连接到另一个标记,则它们不会自动扩展。

C99 6.10.3.1/1:

在确定了调用类函数宏的参数后,将进行参数替换。替换列表中的参数,除非前面有 # 或 ## 预处理标记或后跟 ## 预处理标记(见下文),在其中包含的所有宏都已展开后,将替换为相应的参数。在被替换之前,每个参数的预处理标记都被完全宏替换,就好像它们形成了预处理文件的其余部分一样;没有其他可用的预处理令牌。

您可以通过在传递NAME 的宏和将其与_LEN 连接的宏之间添加另一个宏来解决此问题。

#define NAME ABC
#define AFTERX(x) x##_LEN
#define XAFTERX(x) AFTERX(x)
#define LOG_SIZE XAFTERX(NAME)

LOG_SIZE
//evaluates to ABC_LEN

如果您有兴趣,gcc 手册会更详细地介绍Section 3.10.6: Argument Prescan

【讨论】:

以上是关于在 C 中的宏中替换宏的主要内容,如果未能解决你的问题,请参考以下文章

C/C++ 宏中的逗号

宏中的波浪号 (~) 是啥意思?

如何用C中#define宏中的字符串常量替换函数名

有没有办法删除 C 宏中的引号?

在 Google Sheet 宏中查找和替换

Common Lisp宏中的词法绑定