宏定义中的"#"与“##”

定义

“#”是将宏字符串化(Stringification),“##”是将##左右两边的标签拼接在一起(## is called token concatenation, used to concatenate two tokens in a macro invocation)

例子

看一段代码

#include<stdio.h>

#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)

int main()
{
printf("%s\n", h(f(1,2)));
printf("%s\n", g(f(1,2)));

return 0;
}

输出是:

12
f(1,2)

g(f(1,2))->stringification(f(,1,2))->f(1,2)
h(f(1,2))->h(1##2)->g(12)->#12->12

原因

在宏预扫描((macro prescan)阶段,宏参数首先会被替换,替换之后,再经过下次的扫描完成最后宏的展开(macro expand)。GCC在宏预处理阶段,特意加上了一条排外规则,那就是若宏参数被用于字符串化或者与其它标签连接,则不会被替代!下面是摘抄的一段预处理规则:

Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringized or pasted with other tokens. After substitution, the entire macro body, including the substituted arguments, is scanned again for macros to be expanded. The result is that the arguments are scanned twice to expand macro calls in them.

Reference

[1].https://stackoverflow.com/questions/6503586/what-does-in-a-define-mean
[2].http://blog.chinaunix.net/uid-27714502-id-3461678.html
[3]. https://www.2cto.com/kf/201303/195299.html
[4]. https://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值