本文轉自徐飛翔的“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