宏扩展的具体步骤是什么? [英] What's the exact step of macro expanding?

查看:23
本文介绍了宏扩展的具体步骤是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这没有按预期工作:

#define stringify(x) #x  
printf("Error at line " stringify(__LINE__));

这行得通:

#define stringify1(x) #x  
#define stringify(x) stringify1(x)  
printf("Error at line " stringify(__LINE__));  

预处理用于扩展此类宏的优先级是什么?

What's the priority that preprocess uses to expand such macros?

推荐答案

当扩展一个宏时,预处理器扩展宏的参数只有当这些参数没有经过字符串化(#) 或标记粘贴 (##) 运算符.所以,如果你有这个:

When expanding a macro, the preprocessor expands the macro's arguments only if those arguments are not subjected to the stringizing (#) or token-pasting (##) operators. So, if you have this:

#define stringify(x) #x
stringify(__LINE__)

然后,预处理器扩展__LINE__,因为它是字符串化操作符的参数.但是,当您这样做时:

Then, the preprocessor does not expand __LINE__, because it's the argument of the stringizing operator. However, when you do this:

#define stringify1(x) #x
#define stringify(x) stringify1(x)
stringify(__LINE__)

然后,当扩展 stringify 时,预处理器将 __LINE__ 扩展为当前行号,因为 x 不与字符串化或stringify 定义中的标记粘贴操作符.然后它展开 stringify1,得到我们想要的.

Then, when expanding stringify, the preprocessor expands __LINE__ to the current line number, since x is not used with either the stringizing or token-pasting operators in the definition of stringify. It then expands stringify1, and we get what we wanted.

C99 标准中的相关语言来自 §6.10.3.1/1:

The relevant language from the C99 standard comes from §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.

第 6.10.3.2 和 6.10.3.3 条继续分别定义 ### 运算符的行为.

Clauses §6.10.3.2 and 6.10.3.3 go on to define the behavior of the # and ## operators respectively.

这篇关于宏扩展的具体步骤是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆