C/C++宏展开顺序

宏展开顺序

宏展开顺序大致可以归结为:

第一步:首先用实参代替形参,将实参代入宏文本中

第二步:第一步代入实参后,分两种情况:

1、实参之前遇到#或或之后遇到##,不管实参是不是宏,实参都将不再展开

2、如果实参前后没有#或##,那就继续展开实参,展开发现还是宏则继续展开,直到展开到不能展开为止

第三步:最后继续处理宏替换后的宏文本,如果仍包含宏,则继续展开

参考:https://blog.csdn.net/FJDJFKDJFKDJFKD/article/details/83385708

宏展开的几个注意事项:

1、每次宏展开的结果会被重复扫描,直到没有任何可展开的宏为止。

2、每展开一个宏,都会记住这次展开,在这个宏展开的结果及其后续展开中,不再对相同的宏做展开。宏不能自引用:https://gcc.gnu.org/onlinedocs/cpp/Self-Referential-Macros.html

3、带参数的宏,先对参数做展开,除非宏定义体中包含#或##

a) #表示将后续标识符转换为字符串

b) ##表示将两个标识符连接成一个标识符

c) 注意参数展开的结果中即使有逗号(,),也不视为参数的分隔符

如果宏定义中带有参数,而代码中出现同样标识符时没有参数,不视为宏。

参考:https://www.cnblogs.com/aquastone/p/c-macro-expansion.html
https://blog.csdn.net/KeLiaoo/article/details/109329661

编译阶段打印宏内容

首先介绍#pragma message 。 它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:

#pragma message(“消息文本”)

假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法

#ifdef _X86
#pragma message(“_X86 macro activated!”)
#endif

下面的示例演示如何在编译阶段打印宏内容。

//两个用于测试的宏
#define PI 3.1415926
#define MAX(a,b) (a)>(b) ? (a) :(b)


//首先定义两个辅助宏
#define   PRINT_MACRO_HELPER(x)   #x  
#define   PRINT_MACRO(x)   #x": "PRINT_MACRO_HELPER(x)  

//编译阶段打印宏内容
#pragma message(PRINT_MACRO(PI))
#pragma message(PRINT_MACRO(PI2))
#pragma message(PRINT_MACRO(MAX(a,b)))
#pragma message(PRINT_MACRO(MAX(x,y)))

结果输出
note: #pragma message: PI=3.1415926  
//PRINT_MACRO中的两个x都被替换为PI,PRINT_MACRO_HELPER中的#x替换为宏PI的内容
note: #pragma message: PI2=PI2          
//PI2不存在的情况下PRINT_MACRO_HELPER将#x换做PI2
note: #pragma message: MAX(a,b)=(a)>(b) ? (a) :(b)
note: #pragma message: MAX(x,y)=(x)>(y) ? (x) :(y)

参考:https://blog.csdn.net/xshbx/article/details/7981564

原文地址:https://www.cnblogs.com/JFHS/p/14689678.html