- 论坛徽章:
- 0
|
Thank you。 我在stackoverflow上找到了一些解决办法,似乎用goto语句还是比较有用的。
like:
stackoverflow
For me do{...}while(0) is fine. If you don't want to see the do{...}while(0), you can define alternative keywords for them.
Example:
#define BEGIN_TEST do{
#define END_TEST }while(0);
BEGIN_TEST
if(!condition1) break;
if(!condition2) break;
if(!condition3) break;
if(!condition4) break;
if(!condition5) break;
//processing code here
END_TEST
I think the compiler will remove the unneccessary while(0) condition in do{...}while(0) in binary version and convert the breaks into unconditional jump. You can check it's assembly language version to be sure.
Using goto also produces cleaner code and it is straightforward with the condition-then-jump logic. You can do the following:
{
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.
Note the label is placed after the closing }. This is the avoid one possible problem in goto that is accidentally placing a code in between because you didn't see the label. It is now like do{...}while(0) without condition code.
To make this code cleaner and more comprehensible, you can do this:
#define BEGIN_TEST {
#define END_TEST(_test_label_) }_test_label_:;
#define FAILED(_test_label_) goto _test_label_
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)
With this, you can do nested blocks and specify where you want to exit/jump-out.
#define BEGIN_TEST {
#define END_TEST(_test_label_) }_test_label_:;
#define FAILED(_test_label_) goto _test_label_
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)
|
|