码迷,mamicode.com
首页 > 其他好文 > 详细

do while(0)的作用

时间:2015-06-02 17:25:51      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

阅读Mitsuba的代码的时候,发现了一个有意思的地方:

#define Log(level, fmt, ...) do { \
        mitsuba::Thread *thread = mitsuba::Thread::getThread();         if (EXPECT_NOT_TAKEN(thread == NULL))             throw std::runtime_error("Null thread pointer");         mitsuba::Logger *logger = thread->getLogger();         if (logger != NULL && level >= logger->getLogLevel())             logger->log(level, m_theClass,                 __FILE__, __LINE__, fmt, ## __VA_ARGS__);     } while (0)

定义了一个Log的宏函数,使用了do{...} while(0)的语法,这里的while中的条件是常量0,上面的代码永远只执行一遍。

感觉是多此一举,做法令人费解。上stack overflow查了下资料。说法很多,我在下面归纳两条比较有价值的分析:

1.就是上面的宏定义中,do{}while(0)的意义:

可以先看看Log宏函数如何被使用的:

Log(EInfo, "The time cost by init is %f",Time_stas::init_time);

Log别当作了一个函数来使用,所以,宏定义替换函数后,需要保证语义不会受到影响。

假设这样的场景:

if( xxxx)

Log(xxx,"xxxxx");

else

xxxx;

如果我们不使用do{}while(0),使用{}把do{}中的语句括住。

上面的语句就成了:

if(xxxx)

{....};

else

就会出现编译错误。

当然,使用

if(xxxx){

Log(xxx,xxx);

}else

{

}

可以避免上面使用{}的问题。但是,do{}while(0)的确为一种稳健的做法。

 

2.使用do{}while(0),可以使用break语句,从do中跳出,避免goto语句:

int test(int p)
{
  if(p==-1)
   {
       ...//do something
       goto smaecode;
    }  
   if(p ==0)
   {
     ...//do something
     goto smaecode;
   }
   if(p==1)
  {
      ...//do something
     goto smaecode;
  }
samecode:
     ...//do something
    
    return p;

}

在do{}while(0)内部使用break语句可以避免使用goto:

int test(int p)
{
do
{
  if(p == -1)
  {
    ..//do something 
    break;
  }
  if(p==0)
  {
    ..//do something
    break;
  }
  if(p == 1)
  {
    ..//do something
    break;
  }

}while(0);
...//same code
 return p ;
}

 

do while(0)的作用

标签:

原文地址:http://www.cnblogs.com/wangpei0522/p/4546752.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!