1.引子
#define cat(x, y) x ## y
那么cat(a, b)和cat(cat(a, b), c)的结果是啥.
#define str_impl(x) #x
#define str(x) str_impl(x)
的意图何在.
2.规则
宏替换是C/C++的预处理中的一部分,在C++标准中有4条规则来定义替换.
规则1:实参替换.
本条规则描述带参数的宏的替换过程.
对于宏定义中的形参,在替换列表中,如果不是作为#或##的操作数,那么将对应实参完全
展开(相当于对实参进行求值),然后将替换列表中的形参替换掉.如果是#或##的操作数,
那么不进行替换.
规则2:多次扫描.
在所有的形参替换为实参后,对结果进行再次扫描,如果发现还有可替换的宏,则进行替换,
否则中止.
规则3:递归替换抑制.
如果在替换列表中发现当前正在展开的宏的名字,那么这里不进行替换.更进一步,在嵌套
的替换过程中发现已经替换过的宏的名字,则不进行替换.
规则4:递归预处理抑制.
如果替换后的结果形成预处理指令,则不执行这条预处理指令.
3.实例
#define cat(x, y) x ## y
在cat(cat(a, b), c)中,首先扫描替换列表,发现x和y两个形参作为##的操作数,那么直接
将实参不作任何处理地搬过来,并进行连接运算,得到结果是cat(a, b)c
若在此基础上增加
#define xcat(x, y) cat(x, y)
在xcat(xcat(a, b), c)中首先对x进行求值,也就是先计算xcat(a, b)的结果,容易得到
值是ab.然后对y进行求值,发现不必进行任何处理,值是c,得到结果cat(ab, c).
然后应用规则2,对cat(ab, c)进行求值,容易得到结果是abc.
显然
#d