If you are a C programmer, you must be familiar with macros, they are very powerful, if used correctly can make your work more effective. Then, if you're defining macros and you're not checking them out at random, then they can make you mad and waste n more time. In many C programs, you may see a number of more specific macro definitions that seem less straightforward. Here's an example:
1 #define _set_taks_state (tsk, State_value) 2do {tsk->state = State_value;} while (0)
There are many uses of do{in the Linux kernel and some other well-known C libraries ...} The macro definition for while (0) . What is the purpose of this macro? What are the benefits?
Coogle's Robert Love (formerly engaged in Linux kernel development) gives us answers to the following:
Do {...} while (0) in C is the only constructor that allows you to define a macro that always works the same way, so that no matter how you use the macro (especially if you don't surround the statement that calls the macro with curly braces), the semicolon behind the macro is the same effect.
This sentence may sound a bit awkward, in fact, in a nutshell is: the use of do{...} while (0) the constructed macro will not be affected by curly braces, semicolons, etc., and will always be invoked the way you expect them to run.
For example:
1 #define Foo (x) bar (x); Baz (x)
Then you might call this:
1 foo (wolf);
This expands the macro to:
Bar (Wolf); Baz (Wolf);
This is indeed the right output that we expect. Here's a look if we call this:
1 if (! Feral) 2 Foo (wolf);
Then the expansion may not be the result you expect. The above statement may be extended to:
1 if (! Feral) 2 Bar (Wolf); 3 baz (Wolf);
Obviously, this is a mistake and one of the mistakes that we are often prone to make.
In almost all cases, it is not possible to expect to write multi-statement macros to achieve the correct results. You can't let a macro behave like a function--without do/while (0).
If we use do{...} while (0) to redefine, namely:
1 #define Foo (x) do{bar (x); Baz (x);} while (0)
Now that the statement is functionally equivalent to the former, do ensures that the logic of the curly braces is executed, while the while (0) ensures that the logic is executed only once, which is the same as when there is no loop.
For the above if statement, it will be extended to:
1 if (! Feral) 2 Do {bar (wolf); Baz (Wolf);} while (0);
Semantically, it is equivalent to the following statement:
1 if (! Feral) {2 Bar (Wolf); 3 Baz (Wolf); 4 }
Here you may be puzzled, why not use curly braces to surround the macro directly? Why do you have to use Do/while (0) logic?
For example, we use curly braces to define macros:
1 #define foo (x) {bar (x); Baz (x);}
This can actually be extended correctly for the IF statement above, but what if we call it again as a statement??
1 if (! Feral) 2 foo (wolf); 3 Else 4 Bin (Wolf);
After the macro expands, it becomes:
1 if (! Feral) {2 Bar (Wolf); 3 Baz (Wolf); 4 }; 5 Else 6 Bin (Wolf);
As you can see, there is a problem with grammar.
Summary: Macros in Linux and other code libraries surround execution logic with Do/while (0), because it ensures that macros behave the same, regardless of how many semicolons and curly braces are used in the code.
Citation: Http://www.pixelstech.net/article/1390482950-do-%7B-%7D-while-%280%29-in-macros
Do{...} while (0) the role of the macro definition