本文转自徐飞翔的“do{}while(false)结构的妙用”
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
看源码的时候,发现某个框架的源码里面经常出现如下片段:
do{
if (ASSERT(some_input_1) && ASSERT(some_input_2)) {
...
}
} while(false)
我对于do{} while(false)
结构的使用,在此之前无非两种,第一种是基本用法,也就是把它当成循环结构使用,和for(;;)
,while(){}
没太大区别;还有一种用法是用在宏定义中,如下所示:
#define LARGER(x,y) x > y? x:y
int a = 2 * LARGER(10,30);
此时我们本来期望a = 60,其实因为字符替代的原因,实际上是int a = 2 * x > y?x:y =30。这就是bug的源头之一。通过do{macro_code} while(false)结构,能对macro_code进行很好的分割。
然而,这个结构还有一个好处,其本质是一个循环结构,意味着它可以提前break,在多条件判断的环境下是一个作为对goto
的很好的取代。如:
do {
if (ASSERT(some_input_1) && ASSERT(some_input_2)) {
ERR_LOG('log_info', pFile);
break;
}
if (IS_EXIST(path)) {
ERR_LOG('log_info', pFile);
break;
}
// the residual code you need , the main stream
} while(false)
通过这种手段,基于作为入口条件判断,如果一旦不符合条件,可以直接break,跳到循环之外,这相当于很好地应用了goto的功能,而没有引入goto的负作用(全局跳转,难以维护)。
Reference
[1]. https://stackoverflow.com/questions/2314066/do-whilefalse