In C + +, there are three types of loop statements: for, while, and Do...while, but in the general application loop, we may use for and while to more, do...while relatively less attention.
But when we read the code for our project recently, we found some very clever uses of do...while, not for loops, but for other things to improve the robustness of the code.
1. Do...while (0) eliminates goto statements.
Typically, if you start allocating resources in a function, and then exit the function if you encounter an error halfway through the execution, then, of course, release the resource before exiting, our code might be:
version 1
BOOL Execute ()
{
Allocating resources
int * p = new int;
BOOL BOk (TRUE);
Execute and make error handling
BOk = Func1 ();
if (! bOk)
{
Delete p;
p = NULL;
return false;
}
BOk = Func2 ();
if (! bOk)
{
Delete p;
p = NULL;
return false;
}
BOk = Func3 ();
if (! bOk)
{
Delete p;
p = NULL;
return false;
}
// ..........
Execution succeeded, releasing resources and returning
Delete p;
p = NULL;
return true;
}
One of the biggest problems here is the redundancy of the code, and with each additional operation I need to do the appropriate error handling, very inflexible. So we thought of Goto:
Version 2
BOOL Execute ()
{
Allocating resources
int * p = new int;
BOOL BOk (TRUE);
Execute and make error handling
BOk = Func1 ();
if (! bOk) goto Errorhandle;
BOk = Func2 ();
if (! bOk) goto Errorhandle;
BOk = Func3 ();
if (! bOk) goto Errorhandle;
// ..........
Execution succeeded, releasing resources and returning
Delete p;
p = NULL;
return true;
Errorhandle:
Delete p;
p = NULL;
return false;
}
Code redundancy is eliminated, but we introduced C + + in the more subtle identity of the Goto statement, although the correct use of Goto can greatly improve the flexibility and simplicity of the program, but too flexible things are often very dangerous, it will make our program unpredictable, so how to avoid using the goto statement, and to eliminate code redundancy, see Do...while (0) Loop:
Version3
BOOL Execute ()
{
Allocating resources
int * p = new int;
BOOL BOk (TRUE);
Todo
{
Execute and make error handling
BOk = Func1 ();
if (! bOk) break;
BOk = Func2 ();
if (! bOk) break;
BOk = Func3 ();
if (! bOk) break;
// ..........
while (0);
Releasing resources
Delete p;
p = NULL;
return bOk;
}
Beautiful "Just look at the code, nothing to say ...
2 do...while in macro definition (0)
If you are a C + + programmer, I have reason to believe that you have used, or contacted, at least heard of MFC, in the MFC Afx.h file, you will find that many macro definitions are used Do...while (0) or Do...while (false), such as:
#define AFXASSUME (COND) do {bool __afx_condval=!! (cond); ASSERT (__afx_condval); __analysis_assume (__afx_condval); } while (0)
It would be strange to see that, since the loop only executes once, what is the point of this seemingly superfluous do...while (0)?
Of course.
To make it look clearer, here's a simple point macro to demonstrate:
#define SAFE_DELETE (P) do{DELETE p p = NULL} while (0)
Let's say this removes Do...while (0),
#define SAFE_DELETE (P) DELETE p; p = NULL;
So the following code:
if (NULL!= p) safe_delete (p)
else ... do sth ...
There are two problems,
1) Because there are two statements after the IF branch, the Else branch does not have the corresponding if, compilation failed
2 Assuming that there is no else, the second statement in Safe_delete executes forever regardless of if the if test passes.
You may find that, in order to avoid these two problems, I do not need to use this puzzling do...while, I directly in {} enclosed
#define SAFE_DELETE (P) {DELETE p; p = NULL;}
Indeed, the problem above is not there, but I think for C + + programmers, it is a customary custom to add a semicolon after each statement, so the following code:
if (NULL!= p) safe_delete (p);
else ... do sth ...
The Else branch cannot be compiled (for the reason above), so using Do...while (0) is a good choice. Perhaps you will say, our code custom is after each judgment adds {}, does not have this kind of question, also does not need do...while, like:
if (...)
{
}
Else
{
}
Admittedly, it's a good programming habit that should be advocated, but generally such macros appear as part of the library, and for the author of a library, all he has to do is make his library generic and robust, so he cannot have any assumptions about the user of the library, such as its coding specifications, Technology and so on.
Thank the original author. Recently, I always see such a Do while (0), always feel strange, puzzled its meaning, today finally understand. Let's say thank you for sharing your experience with the original author.
Turn from: http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html