宏定义中的do{ }while(0)

无论是Linux内核还是其他著名的c、c++库里都能见到 do{} while (0) 

这样的写法看似没有意义,其实出自名家之手,是在宏定义里使用的 

以前就了解到在程序里使用宏定义的函数后面的分号容易导致问题,今天算是深入认识了 

先看一个简单的宏 

#define SAFE_FREE(p) do {free(p);p=NULL;} while(0) 

如果去掉了do... while(0) 

即定义SAFE_FREE(p)为 

#define SAFE_FREE(p) free(p);p=NULL; 

那么下面的代码 

if(NULL!=p) 

SAFE_FREE(p) 

else 

//do something 

将被展开为: 

if(NULL!=p) 

free(p);p=NULL; 

else 

//do something 

这样就导致if后面有两条语句,第二条语句总会执行,且else不再与原来的if匹配 

所以一般聪明的人在定义宏函数的时候会加上 {} 

#define SAFE_FREE(p) { free(p);p=NULL;} 

这样貌似解决了问题,可是还是有隐患 

因为很多人习惯在C代码最后都加 ; 

没有经验的人往往会不管那个SAFE_FREE(p)全是大写,直接在后面加上; 

如 

if(NULL!=p) 

SAFE_FREE(p); 

else 

//do something 

被展开为 

if(NULL!=p) 

{ free(p);p=NULL;}; 

else 

//do something 

这样 仍然导致if和else的匹配被破坏的情况 

如果使用名家的方法 

#define SAFE_FREE(p) do {free(p);p=NULL;} while(0) 

那么 

if(NULL!=p) 

SAFE_FREE(p); 

else 

//do something 

展开为 

if(NULL!=p) 

do 

{ free(p);p=NULL;} 

while(0); 

else 

//do something 

好了 这样就一切太平了 

书上是这么说,可是我认为虽然采用了 

#define SAFE_FREE(p) do {free(p);p=NULL;} while(0) 这样的定义 

可是使用者要是突然意识到SAFE_FREE(p)是个宏,然后自作聪明没有在SAFE_FREE(p)后加; 

如 

if(NULL!=p) 

SAFE_FREE(p) 

else 

//do something 

这样展开 

if(NULL!=p) 

do 

{ free(p);p=NULL;}; 

while(0) 

else 

//do something 

这样while(0)后面没有; 仍然报错! 

聪明反被聪明误,只因为还不够聪明。 

解决问题最简单的方法就是良好的编程习惯 

一个没有任何问题的if else结构就能解决所有的问题 

if(NULL!=P) 

{//do something } 

else 

{ //do something } 

就是两点,NULL!=P而不是p!=NULL ,还有就是齐全的{}匹配 

说来容易,但是我们在网上甚至是名著里仍然很难看到完美的写法 

不要偷懒,少打那么几个{},否则会付出更惨痛的代价
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值