简体   繁体   English

在 C 中的宏中替换宏

[英]Substituting macros within macros in C

I'm trying to make a code-section reusable.我正在尝试使代码段可重用。 My comment snippet below isn't doing what I want it to:我下面的评论片段没有做我想要的:

#define NAME ABC 
#define LOG_SIZE NAME##_LEN 

I would like LOG_SIZE to resolve to ABC_LEN .我希望LOG_SIZE解析为ABC_LEN I've tried playing around with the #'s, but haven't been able to get this to work.我试过玩弄#,但一直无法让它发挥作用。 LOG_SIZE is used all over the code, so I don't want to change the macro to: LOG_SIZE用于整个代码,所以我不想将宏更改为:

#define LOG_SIZE(name) name##_LEN

Is there a way to do this?有没有办法做到这一点?

The problem is that macro arguments aren't automatically expanded if they would be stringified or concatenated to another token.问题在于,如果宏参数被字符串化或连接到另一个标记,则它们不会自动展开。

C99 6.10.3.1/1: C99 6.10.3.1/1:

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place.在确定调用类函数宏的参数后,将进行参数替换。 A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded.替换列表中的参数,除非前面有 # 或 ## 预处理标记或后跟 ## 预处理标记(见下文),否则在其中包含的所有宏都已展开后由相应的参数替换。 Before being substituted, each argument's preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file;在被替换之前,每个参数的预处理标记被完全宏替换,就好像它们形成了预处理文件的其余部分一样; no other preprocessing tokens are available.没有其他预处理令牌可用。

You can get around this by adding another macro in between the one that passes NAME and the one that concatenates it with _LEN .您可以通过在传递NAME宏和将其与_LEN连接的宏之间添加另一个宏来解决此_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

The gcc manual goes into further detail if you're curious, in Section 3.10.6: Argument Prescan如果您好奇,gcc 手册会在第 3.10.6 节:参数预扫描中更详细地介绍

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

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