“do while”和“goto out”在这些领域是不同的:
1.局部变量初始化
void foo(bool t = false)
{
if (t)
{
goto DONE;
}
int a = 10; // error : Goto bypass local variable's initialization
cout << "a=" << a << "\n";
DONE:
}
可以在 do ... while(0) 块中初始化就地局部变量。
void bar(bool t = false)
{
do{
if (t)
{
break;
}
int a = 10; // fine
cout << "a=" << a << "\n";
} while (0);
}
2 宏的区别。“do while”稍微好一点。宏中的“goto DONE”并非如此。如果退出代码更复杂,让我们看看:
err = some_func(...);
if (err)
{
register_err(err, __LINE__, __FUNC__);
#if defined (_DEBUG)
do_some_debug(err)
#endif
break;
}
而你一次又一次地编写这段代码,你可能会将它们放入一个宏中。
#define QUIT_IF(err) \
if (err) \
{ \
register_err(err, __LINE__, __FUNC__); \
DO_SOME_DEBUG(err) \
break; // awful to put break in macro, but even worse to put "goto DONE" in macro. \
}
代码变为:
do
{
initial();
do
{
err = do_step1();
QUIT_IF(err);
err = do_step2();
QUIT_IF(err);
err = do_step3();
QUIT_IF(err);
....
} while (0);
if (err) { // harder for "goto DONE" to get here while still using macro.
err = do_something_else();
}
QUIT_IF(err);
.....
} while (0);
3.do... while(0) 使用相同的宏处理不同级别的退出。代码如上所示。goto ... 不是 Macro 的情况,因为您需要不同级别的不同标签。
这么说,我两个都不喜欢。我更喜欢使用异常方法。如果不允许异常,那么我使用“do ... while(0)”,因为整个块是缩进的,实际上它比“goto DONE”样式更容易阅读。