对我do{...}while(0)
来说很好。如果您不想看到do{...}while(0)
,您可以为它们定义替代关键字。
例子:
SomeUtilities.hpp:
#define BEGIN_TEST do{
#define END_TEST }while(0);
SomeSourceFile.cpp:
BEGIN_TEST
if(!condition1) break;
if(!condition2) break;
if(!condition3) break;
if(!condition4) break;
if(!condition5) break;
//processing code here
END_TEST
我认为编译器将删除二进制版本中不必要的while(0)
条件do{...}while(0)
并将中断转换为无条件跳转。你可以检查它的汇编语言版本来确定。
使用goto
还可以生成更清晰的代码,并且使用条件然后跳转逻辑很简单。您可以执行以下操作:
{
if(!condition1) goto end_blahblah;
if(!condition2) goto end_blahblah;
if(!condition3) goto end_blahblah;
if(!condition4) goto end_blahblah;
if(!condition5) goto end_blahblah;
//processing code here
}end_blah_blah:; //use appropriate label here to describe...
// ...the whole code inside the block.
注意标签是在关闭之后放置的}
。这是避免一个可能的问题,goto
即由于您没有看到标签而意外在两者之间放置了代码。现在就像do{...}while(0)
没有条件代码一样。
为了使这段代码更清晰、更易于理解,你可以这样做:
SomeUtilities.hpp:
#define BEGIN_TEST {
#define END_TEST(_test_label_) }_test_label_:;
#define FAILED(_test_label_) goto _test_label_
SomeSourceFile.cpp:
BEGIN_TEST
if(!condition1) FAILED(NormalizeData);
if(!condition2) FAILED(NormalizeData);
if(!condition3) FAILED(NormalizeData);
if(!condition4) FAILED(NormalizeData);
if(!condition5) FAILED(NormalizeData);
END_TEST(NormalizeData)
有了这个,您可以执行嵌套块并指定要退出/跳出的位置。
BEGIN_TEST
if(!condition1) FAILED(NormalizeData);
if(!condition2) FAILED(NormalizeData);
BEGIN_TEST
if(!conditionAA) FAILED(DecryptBlah);
if(!conditionBB) FAILED(NormalizeData); //Jump out to the outmost block
if(!conditionCC) FAILED(DecryptBlah);
// --We can now decrypt and do other stuffs.
END_TEST(DecryptBlah)
if(!condition3) FAILED(NormalizeData);
if(!condition4) FAILED(NormalizeData);
// --other code here
BEGIN_TEST
if(!conditionA) FAILED(TrimSpaces);
if(!conditionB) FAILED(TrimSpaces);
if(!conditionC) FAILED(NormalizeData); //Jump out to the outmost block
if(!conditionD) FAILED(TrimSpaces);
// --We can now trim completely or do other stuffs.
END_TEST(TrimSpaces)
// --Other code here...
if(!condition5) FAILED(NormalizeData);
//Ok, we got here. We can now process what we need to process.
END_TEST(NormalizeData)
意大利面条代码不是程序员的错goto
,而是程序员的错。您仍然可以在不使用goto
.