宏定义中使用do{}while(0)的好处

来源:互联网 发布:淘宝主宝贝副宝贝意思 编辑:程序博客网 时间:2024/04/29 02:45
#define MACRO_NAME(para) do{macro content}while(0)
的格式,总结了以下几个原因:
1,空的宏定义避免warning:
#define foo() do{}while(0)
2,存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现。
3,如果出现在判断语句过后的宏,这样可以保证作为一个整体来是实现:
#define foo(x) /action1(); /action2();
在以下情况下:
if(NULL == pPointer)   foo();
就会出现action1和action2不会同时被执行的情况,而这显然不是程序设计的目的。
 
4,以上的第3种情况用单独的{}也可以实现,但是为什么一定要一个do{}while(0)呢,看以下代码:
#define switch(x,y) {int tmp; tmp="x";x=y;y=tmp;}if(x>y)  switch(x,y);else       //error, parse error before else  otheraction();
在把宏引入代码中,会多出一个分号,从而会报错。
 
//------------------------------------------------
使用do{….}while(0) 把它包裹起来,成为一个独立的语法单元,
从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无
用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低

在C++中,有三种类型的循环语句:for, while, 和do...while,
但是在一般应用中作循环时, 我们可能用for和while要多一些,do...while相对不受重视。
但是,最近在读我们项目的代码时,却发现了do...while的一些十分聪明的用法,不是用来做循环,而是用作其他来提高代码的健壮性。

5,do...while(0)消除goto语句。
通常,如果在一个函数中开始要分配一些资源,然后在中途执行过程中如果遇到错误则退出函数,
当然,退出前先释放资源,我们的代码可能是这样:
bool Execute(){   // 分配资源   int *p = new int;   bool bOk(true);   // 执行并进行错误处理   bOk = func1();   if(!bOk)    {      delete p;         p = NULL;      return false;   }   bOk = func2();   if(!bOk)    {      delete p;         p = NULL;      return false;   }   bOk = func3();   if(!bOk)    {      delete p;         p = NULL;      return false;   }   // ..........   // 执行成功,释放资源并返回    delete p;       p = NULL;    return true;   }
这里一个最大的问题就是代码的冗余,而且我每增加一个操作,就需要做相应的错误处理,非常不灵活。
于是我们想到了goto:
version 2
bool Execute(){   // 分配资源   int *p = new int;   bool bOk(true);   // 执行并进行错误处理   bOk = func1();   if(!bOk) goto errorhandle;   bOk = func2();   if(!bOk) goto errorhandle;   bOk = func3();   if(!bOk) goto errorhandle;   // ..........   // 执行成功,释放资源并返回    delete p;       p = NULL;    return true;errorhandle:    delete p;       p = NULL;    return false;   }
代码冗余是消除了,但是我们引入了C++中身份比较微妙的goto语句,
虽然正确的使用goto可以大大提高程序的灵活性与简洁性,
但太灵活的东西往往是很危险的,它会让我们的程序捉摸不定,
那么怎么才能避免使用goto语句,又能消除代码冗余呢?
请看do...while(0)循环:
version3
bool Execute(){   // 分配资源   int *p = new int;   bool bOk(true);   do   {      // 执行并进行错误处理      bOk = func1();      if(!bOk) break;      bOk = func2();      if(!bOk) break;      bOk = func3();      if(!bOk) break;      // ..........   }while(0);    // 释放资源    delete p;       p = NULL;    return bOk;}

来自:http://blog.csdn.net/liliangbao/article/details/4163440
原创粉丝点击