宏展开顺序分析

The sequence of preprocessing tokens bounded by the outside-most matching parentheses
forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens. but comma preprocessing tokens between matching inner parentheses do not separate arguments.

6.8.3.1 Argument substitution
After the arguments for the invocation of a function-like niacro 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 translation unit: no other preprocessing tokens are available.

总结上述的内容,就是两点:

1。最外层括号中的逗号为实参分隔符,内层的不分隔该层实参;
2。带有预处理指令#或/和##的形参,不参与宏替换或 宏展开


对于
#define cat(a,b) a ## b
cat(cat(1,2),3)

我们首先来分隔实参,这里有两个逗号,根据第一点,3左边的逗号是用来分隔最外层实参的,里面那个逗号在这一层的宏中不是实参分隔符,注意我说的是在这一层,这时候a = cat(1,2),b=3。接着继续进行 宏展开 或替换,由于a的后面和b的前面都有##指令,根据第二点,此时a和b都不再进行宏替换,因此a就是cat(1,2),b就是3,再进行粘贴,结果就是cat(1,2)3


对于
#define f(a) fff a
f(cat(cat(1,2),3))

cat(cat(1,2),3)整个就是a,由于a的前面后面都没有#和##,因此根据第二点继续进行宏替换,3左边的逗号是该层的实参分隔符,因此a=cat(1,2),b=3,继续根据第二点进行宏替换,a=1,b=2,于是就是(1##2)##3,结果就是fff 123


同样的道理可以用来分析
#define cat(a,b) a##b
#define xcat(a,b) cat(a,b)
xcat(xcat(1,2),3)

我用简化的步骤来一层一层替换下去:
xcat(xcat(1,2),3)
xcat(cat(1,2),3)
xcat(1##2, 3)
cat(1##2,3)
1##2##3
123


我在这里再补充一种情况,就是对于
#define N 10

如果想制造字符串化效果"10",应该怎么做?

直接#define X(N) #N是不行的,根据第一点,结果只会是"N",而不是"10",这时候应该这样定义宏:

#define N 10
#define Y(N) X(N)
#define X(N) #N

让Y(N)中的N先替换为10,就可以得到"10"了。

PS:宏展开从外层进行,将外层的参数展开,最后才是对外层展开


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值