GCC扩展符(#,##)

先来说说这两个扩展符的各自用处吧 ,“#”是将宏字符串化(Stringification),“##”是将##左右两边的标签组合在一起(token pasting or token concatenation),下面从两个简单例子着手:
[cpp]  
#define SSVAR(X,Y) const char X[]=#Y  
SSVAR(InternetGatewayDevice, InternetGatewayDevice.);  
  上面这个例子实质是借用了#扩展符去实现名为InternetGatewayDevice的字符数组初始化,其等价代码(可以通过gcc –E展开获得)如下:
[cpp]  
const char InternetGatewayDevice[]="InternetGatewayDevice.";  
   下面这个例子比较常见,用于打开不同的路径。
[cpp]  
#define DEV_FILE_NAME    "/dev/test_kft"  
  
#define OPEN_FILE(fd, n) \  
{  \  
      fd = open(DEV_FILE_NAME ##n, 0); \  
   if (fd < 0) \  
   { \  
      printf("Open device error/n"); \  
      return 0; \  
   } \  
}  
OPEN_FILE(fd1, 1);  
OPEN_FILE(fd2, 2);  
   其展开的等价代码如下:
[cpp]  
{ fd1 = open(DEV_FILE_NAME1, 0); if (fd1 < 0) { printf("Open device error/n"); return 0; } };  
{ fd2 = open(DEV_FILE_NAME2, 0); if (fd2 < 0) { printf("Open device error/n"); return 0; } };  
       值得注意的是,##扩展符是用来连接两个标签,但是这两个标签之一不能为空!
       但是使用这两个扩展符,有一个极容易出现错误的地方,那就是宏展开的问题,且看下面这个例子:
[cpp]  
#define xstr(s) str(s)  
#define str(s) #s  
#define foo 4  
  
str(foo); //->”foo”  
xstr(foo); //->xstr(4)->str(4)->”4”  
        为什么str(foo)与xstr(foo)展开之后会出现完全不同的结果呢?此处就涉及到宏展开的规则问题:在宏预扫描((macro prescan)阶段,宏参数首先会被替换,替换之后,再经过下次的扫描完成最后宏的展开(macro expand),OK,说到此,似乎str(foo)在预扫描阶段应该会变成str(4),但是GCC在宏预处理阶段,特意加上了一条排外规则,那就是若宏参数被用于字符串化或者与其它标签连接,则不会被替代!结果也就可想而知了。下面是摘抄的一段预处理规则:
    Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringified or pasted with other tokens. After substitution, the en-tire macrobody, including the substituted arguments, is scanned again for macros to be expanded.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值