使用C/C++中的宏

来源:互联网 发布:淘宝哪个店有原味丝袜 编辑:程序博客网 时间:2024/06/05 23:48

在预处理(preprocess)阶段,编译器会替换掉宏。通过-E选项可以查看预处理后的输出内容

cc -E macro-test.c

替换流程(含脑补)

  1. 按顺序依次解析文件,对每一个输入
  2. 处理掉注释内容
  3. 如果是宏定义,添加到宏集合中。不会对宏定义中的宏展开处理
  4. 展开宏
    1. 宏对象直接替换,其中的##有效,#无效
    2. 宏函数展开
      1. 对#arg直接替换成”arg”形式,并对其中的特殊字符替换成转义形式。(arg必须是某个宏参数名字)
      2. 对A##B替换成AB。当B是可变参数宏(比如__VA_ARGS__)时,如果可变参数为空,且A是一个’,’时,此时A##B直接替换成空,也就是删掉了那个逗号。
      3. 对宏参数完全展开
    3. 如果某个宏展开链中出现循环,停止对这个宏的展开
  5. 继续对生成的内容进行宏展开,直到没有发生展开

宏解析

  1. 一般以空格等其他非标识符字符划分token,多个空格被缩成1个。
  2. 单引号或双引号需要配对,单引号中的双引号可以随意出现,相反也是。
  3. 函数宏区分对象宏在于宏名字后紧跟用圆括号包围的参数列表。参数名符合标识符规则,用逗号隔开,空格可选。
  4. 宏函数内容中的#必须作用在参数之一。一般A##B要求A的最后一个字符和B的首个字符组合满足标识符规则,而且数字可以在前面。A和B中如果出现引号需要满足2 。##前后的空格以及#后面的空格会被吃掉。
  5. 使用宏函数时,宏名和参数可选空格,参数之间可空格,可换行。

测试代码

#define TM(str) __LINE__:#str ==> str#define M1 M0TM(M1)#define M0 object-likeTM(M1)#define M2/* comment as whitespace*/M1TM(M2)#define M3 M3TM(M3)//self-referential#define M4 M4     #None#M2&M1TM(M4)#undef M2#define M2 M4TM(M4)#define M5 a##bTM(M5)#define F0 function-like#define F1(a, b) {a, b, ab, a b, a#b, a# b, a # b, a ## b, F0}TM ( F1 ( a , b ) )#define F2(a, b) {a, b, ab, a#b, a##b}TM(F2(a*'"'3,      b&+"'"-))TM(F2(M0,      #undef M0      #define M0 0      M0))#define M0M1 groupTM(F2(M0,M1)) // F2展开后出现M0M1,这个宏会再次展开#define M1M2 F2(M1, M2)TM(F2(M1,M2))/* M1M2展开后出现F2,M1M2由F2在特定参数下展开生成,这里的宏被算成F2的展开链中,F2出现循环不再展开,但M1M2展开时的参数M1,M2还会展开:   {M1, M2, ab, 0"M2", M1M2}   {0, M4 #None#M2&0, ab, 0"M2", M1M2}   {0, M4 #None#M2&0, ab, 0"M2", F2(M1, M2)}   {0, M4 #NoneM2&0, ab, 0"M2", F2(0, M4 #None#M2&0)} */#define F3(a) #a#define F4(a) F3(a) #aTM(F4(F4(M2))) //宏参数会完全展开

输出

# 1 "macro-test.c"# 1 "<built-in>" 1# 1 "<built-in>" 3# 329 "<built-in>" 3# 1 "<command line>" 1# 1 "<built-in>" 2# 1 "macro-test.c" 24:"M1" ==> M06:"M1" ==> object-like8:"M2" ==> object-like10:"M3" ==> M312:"M4" ==> M4 #None#object-like&object-like15:"M4" ==> M4 #None#M4&object-like17:"M5" ==> ab21:"F1 ( a , b )" ==> {a, b, ab, a b, a"b", a"b", a "b", ab, function-like}24:"F2(a*'\"'3, b&+\"'\"-)" ==> {a*'"'3, b&+"'"-, ab, a*'"'3"b&+\"'\"-", a*'"'3b&+"'"-}28:"F2(M0, M0)" ==> {0, 0, ab, 0"M0", M0M0}30:"F2(M0,M1)" ==> {0, 0, ab, 0"M1", group}32:"F2(M1,M2)" ==> {0, M4 #None#M2&0, ab, 0"M2", F2(0, M4 #None#M2&0)}# 41 "macro-test.c"41:"F4(F4(M2))" ==> "\"M4 #None#M2&0\" \"M2\"" "F4(M2)"
0 0
原创粉丝点击