# Define macro_name (para) do {macro content} while (0) format summarizes the following reasons: 1. Empty macro definition avoids warning:
# Define Foo () do {} while (0) 2, which has an independent block that can be used for variable definition and complex implementation. 3. If the macro appears after the statement is judged, it can be implemented as a whole:
# Define Foo (X )/
Action1 ();/
Action2 ();
In the following cases:
If (null = ppointer)
Foo ();
Action 1 and Action 2 will not be executed at the same time, and this is obviously not the purpose of program design. 4. The above 3rd cases can also be implemented with a separate {}, but why do you need a do {} while (0)? Check 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 (); an extra semicolon will be added when the macro is introduced into the code, and an error will be reported. // -------------------------------------------------- Use do {....} While (0) wraps it into an independent syntax unit,
This will not be confused with the context. At the same time, because most compilers can recognize do {...} While (0)
So using this method will not cause program performance degradation.
Why are many Linux kernel macros # defines used?Do {...} while (0 )?
There are many reasons:
(Dave Miller's statement):
The compiler generates an alarm for null statements. This is why # define Foo do {} while (0 );
Defines many local variables for a given basic block (local field of sight;
(Ben Collins's statement ):
Complex macros can be defined in the condition code. As you can imagine, there are many macros, the following code:
#define FOO(x) /
printf("arg is %s/n", x); /
do_something_useful(x);
Now, imagine the following application:
if (blah == 2)
FOO(blah);
The expanded code is as follows:
if (blah == 2)
printf("arg is %s/n", blah);
do_something_useful(blah);;
- As you can see, if only contains printf (), while do_something_useful () is called unconditionally. Therefore, ifDo {...} while (0), the result is:
if (blah == 2)
do {
printf("arg is %s/n", blah);
do_something_useful(blah);
} while (0);
- This is the expected result.
- (Per Persson ):
- As Miller and Collins pointed out, a block statement must contain multiple code lines and declare local variables. However, the essence is as follows:
#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }
- The above code sometimes cannot work effectively. The following code is an if statement with two branches:
If (x> Y)
exch(x,y); // Branch 1
else
do_something(); // Branch 2
- The expanded code is as follows:
if (x > y) { // Single-branch if-statement!!!
int tmp; // The one and only branch consists
tmp = x; // of the block.
x = y;
y = tmp;
}
; // empty statement
else // ERROR!!! "parse error before else"
do_something();
- The problem is that semicolon (;) appears behind the block. To solve this problem, use do {} while (0 ):
if (x > y)
do {
int tmp;
tmp = x;
x = y;
y = tmp;
} while(0);
else
do_something();
- (Bart trojanowski's statement):
- GCC adds statement explanation, which provides a method to replace do-while-0 blocks. The above solution is as follows, and more common sense
# Define Foo (ARG )({/
typeof(arg) lcl; /
lcl = bar(arg); /
lcl; /
})