Reproduced from: C language in Do...while (0) of the magical, thanks for sharing.
In the Linux kernel code, often see Do...while (0) of the macro, Do...while (0) has a lot of role, the following list of several:
1. Avoid goto statements:
Typically, if a function starts to allocate some resources and then exits the function if it encounters an error halfway, of course, to release resources before exiting, our code might look like this:
1 #defien N 2 3 bool Execute () 4 {5 //Allocated resource 6 int *p = (int *) malloc (N * sizeof (int)); 7 bool bOk = TR Ue 8 9 //execution and error handling . bOk = Func1 (); one if (!bok) ( p); p = null;15 return false;16 }17 bOk = Func2 (); + if (!bok) ( p); p = null;23 return false;24 }25- bOk = func3 (), if (!bok), ( p); The p = null;31 return false;32 }33 //..... the success of the implementation, the release of resources and the return of the PNs free (p); p = null;39 return true;40}
The biggest problem here is code redundancy, each additional operation, it is necessary to do the corresponding error handling, very inflexible, so think of a goto:
C code
Code redundancy is solved, but introduces the more subtle goto statements in C, although the correct use of the Goto statement can greatly improve the flexibility and simplicity of the program, but will make our program unpredictable, in order to avoid the use of Goto statement, but also to eliminate the code redundancy, you can consider using the following do ... while (0):
C code2. Avoid null declarations at compile time warning:
In the Linux kernel source code, you often see the following macros to avoid warnings at compile time:
#define FOO do {} and (0)
3. Provide a base block for declaring local variables:
You may often use the following macros:
#define EXCH (x, y) {int tmp; tmp=x; x=y; y=tmp;}
However, in some cases it will fail, the code below uses If...else ...
if (x > Y) Exch (y); Branch 1else do_something (); Branch 2
But the if statement that will be interpreted as a branch:
if (x > Y) { int tmp; TMP = x; x = y; y = tmp;}; Empty statement Else //ERROR!!! Do_something ();
The error is in the ";" Directly behind the code block, the workaround is to embed the code in Do...while (0) and get the following code:
1 if (x > Y) 2 does {3 int tmp;4 tmp = x;5 x = y;6 y = tmp;7 } while (0); 8 else9 Do_somet Hing ();
So the above macro can be modified to:
1 #define EXCH (x, y) do {2 int. tmp;3 tmp = x;4 x = y;5 y = tmp;6 } while (0)
4. Use complex macros in conditional statements:
If a macro contains several lines of code similar to the following:
#define FOO (x) printf ("Arg is%s\n", x); Do_something_useful (x);
Now imagine the following code:
if (blah = = 2) FOO (Blah);
This will be interpreted as:
if (blah = = 2) printf ("Arg is%s\n", blah); do_something_useful (Blah);
We will find that if statement only works on printf (), do_something_useful () is not executed as intended, that is, not included in the if code as you would expect, so you can use the following code block:
if (blah = = 2) do { printf ("Arg is%s\n", blah); do_something_useful (Blah); } while (0);
So the macro above can be changed to:
1 #define FOO (x) do {2 printf ("Arg was%s\n", blah), 3 do_something_useful (Blah), 4 } while (0)
PS: Above the third and the fourth kind of technique, is not the only method, has the classmate message to say with other method also can realize, instead appears such macro definition too fancy? This is not the case, such macro definitions are very common in Linux kernel code because the code is simple, generic, and portable.
The magical application of Do...while (0) in C language (reproduced)