Benefits of using Do{}while (0) in macro definitions
#define MACRO_NAME (para) Do{macro content}while (0)
Format, summed up the following reasons: 1, empty macro definition to avoid warning: #define FOO () do{}while (0) 2, there is a separate block, can be used for variable definition, a more complex implementation. 3, if the macro appears after the judgment statement, this can be guaranteed as a whole to be implemented:
#define FOO (x)/
Action1 (); /
Action2 ();
In the following cases:
if (NULL = = Ppointer)
Foo ();
There will be situations where action1 and action2 will not be executed at the same time, which is clearly not the purpose of programming.
4, the above 3rd case with a separate {} can also be implemented, but why must be a do{}while (0), see the following code:
#define SWITCH (x, y) {int tmp; tmp= "x"; x=y;y=tmp;}
if (x>y)
switch (x, y);
else /error, parse error before else
Otheraction ();
When you introduce a macro into your code, you will get an error by adding a semicolon.//------------------------------------------------Wrap it up with Do{....}while (0) and become a separate grammar unit,
This will not confuse the context. And because the vast majority of compilers are able to identify do{...} while (0) this non-
and optimized, so using this method does not result in a slow performance of the program in C + +, there are three types of loop statements: for, while, and Do...while,However, in general applications, we may use for and while more, Do...while is relatively not valued.
However, when we read the code of our project recently, we found some very clever usages of do...while, not to do loops, but to use other to improve the robustness of the code.
1. Do...while (0) removes the goto statement. In General, if you start to allocate some resources in a function and then exit the function if you encounter an error during midway execution,of course, freeing up resources before exiting, our code might be like this:
BOOL Execute ()
{
//assigning Resources
int *p =Newint
bool bOk (true);
// Execute and 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;
}
// .....
// Execute successfully, release the resource and return to Delete p;
P = NULL;
return true;
} /span>
one of the biggest problems here is the redundancy of the code, and I need to do the appropriate error handling for each additional operation, which is very inflexible. so we thought of Goto:
version 2
BOOL Execute ()
{
//assigning Resources
int *p = new int;
bool bOk (true);
// Execute and error handling
BOk = Func1 ();
if (!bok) goto Errorhandle;
BOk = Func2 ();
if (!bok) goto Errorhandle;
BOk = func3 ();
if (!bok) goto Errorhandle;
// .....
// Execute successfully, release the resource and return to Delete p;
P = NULL;
return true;
Errorhandle:
Delete p;
P = NULL;
return false;
} /span>
code redundancy is eliminated, but we have introduced a more subtle goto statement in C + +,Although the correct use of Goto can greatly improve the flexibility and simplicity of the program,but things that are too flexible tend to be dangerous, and it can make our programs unpredictable,So how can you avoid using goto statements and eliminate code redundancy?See do...while (0) Loop:
Version3
BOOL Execute ()
{
// Allocate resources
int *p = new int;
bool bOk (true);
do
{
// Execute and error handling
BOk = Func1 ();
if (!bok) break;
BOk = Func2 ();
if (!bok) break;
BOk = func3 ();
if (!bok) break;
// .....
}while (0 ");
// Free resources
Delete p;
P = NULL;
return bOk;
} /span>
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 MFC's Afx.h file,you will find that many macro definitions use Do...while (0) or Do...while (false), such as:
#define AFXASSUME (COND) do {bool __afx_condval=!! (cond); ASSERT (__afx_condval);
While
we'll find it strange to look at it, since the loop only executes once,I want this seemingly superfluous do...while (0) What's the point? Of course!
to look clearer, here's a simple macro to demonstrate:
#define SAFE_DELETE (P) do{DELETE p; p = NULL} while (0)
Let's say we get rid of do...while (0),
#define SAFE_DELETE (P) DELETE p; p = NULL;
Then the following code:
if (NULL! = p) Safe_delete (p)
Else ... Do sth ...
There are two problems,
1) Because if there are two statements after the IF branch, the Else branch has no corresponding if, the compilation fails
2) Assuming there is no else, the second statement in Safe_delete will be executed forever, regardless of whether the if test passes.
You may find that, in order to avoid these two problems, I do not have to use this puzzling do...while, I directly with {} can be
#define SAFE_DELETE (P) {DELETE p; p = NULL;}
It is true that the above problem does not exist, but I think for C + + programmers,
It is customary to add semicolons after each statement, so the following code:
if (NULL! = p) safe_delete (p);
Else ... Do sth ...
The Else branch cannot be compiled (the same reason), so using Do...while (0) is a good choice.
Perhaps you would say that our code habit is to add {} After each judgment, there will be no such problem, there is no need to do...while, such as:
{
}
Else
{
}
Admittedly, this is a good and should be advocated programming habits, but generally such a macro is as part of the library appears,
And for the author of a library, all he has to do is make its library versatile, strong,
Therefore he cannot have any assumptions about the user of the library, such as its coding specifications, technical level, etc.
from: http://blog.csdn.net/liliangbao/article/details/4163440http://www.cnblogs.com/bastard/archive/2011/11/24/2262195.html
Benefits of using Do{}while (0) in macro definitions (reprint)