do {} while (0)的用途

xiaoxiao2026-03-15  11

#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();   就会出现action1action2不会同时被执行的情况,而这显然不是程序设计的目的。

  

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)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。

 

 

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:

 

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)循环: 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; }  
转载请注明原文地址: https://www.6miu.com/read-5045929.html

最新回复(0)