关于打印宏展开结果的解释

转自http://www.1to2.us/-a166067.htm

原文在瀚海星云。请参阅的C标准

因为C的预处理器对于# operator的处理与普通的宏是不同的,假设有

#define STR   abcdefg
#define mkstr(x)  #x
#define showstr(x)      mkstr(x)

那么对于mkstr(STR)和showstr(STR),预处理器的观点是不一样的:

mkstr宏的参数x在宏的替换列表当中直接跟在#的后面这时候预处理器会把它替换成为根
实参的spelling替换得来的字符量。所以mkstr(STR)会被替换成"STR"。

这个C标准规定如下:
[6.10.3.2.2]
If, in the replacement list, a parameter is immediately preceded by a # 
preprocessing token, both are replaced by a single character string literal 
preprocessing token that contains the spelling of the preprocessing token
sequence for the corresponding argument. 

而showstr的参数x在替列表当中并不是直接根在#后面的,所以会执行标准的宏参数替换
。即从内到外的完全的宏替换,即把所有的实参全部展开,再执行当前的宏替换。因此
showstr的参数STR先被完全展开成abcdefg,然后执行showstr的展开,变成
mkstr(abcdefg),进而变成"abcdefg"。

这一段标准条文如下:
[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.

这样,前面的帖子给出的PRINT_MACRO的定义就很容易理解了。第一层展开PRINT_MACRO的时候,要先把参数arg对应的实参完全展开,之后经过__MACRO_S的处理变成文字量,经printf打印出来,获得的就是完整的宏展开之后的字符串了。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值