You is a C programmer, you must is familiar with macros. They is powerful and can help you ease your work if used correctly. However, if you don ' t define macros carefully, they could bite you and drive you crazy. In the many C programs, you could see a special macro definition which may seem isn't so straightforward. Here is one example:
#define __set_task_state (tsk, State_value) do {(tsk)->state = (state_value);} while (0)
There is many this kind of macros which uses do{...} while (0) in the Linux kernels and other popular C libraries. What's the use of this macro? Robert Love from Google (previously worked on Linux kernel development) gives us the answer.
Do{...} while (0) are the only construct in C that lets you define macros that always work the same a-to, so, a semicolon after Y We macro always have the same effect, regardless of the macro is used (with particularly emphasis on the issue of Nest ING the macro in an if without curly-brackets).
For example:
#define FOO (x) bar (x); Baz (x)
Later call:
Foo (wolf);
This'll be expanded to:
Bar (Wolf); Baz (Wolf);
This is the expected output. Next Let's see if we have:
if (!feral) foo (Wolf);
The expansion may is not expect. The expansion may:
if (!feral) bar (Wolf); Baz (Wolf);
It isn ' t possible to write multistatement macros that does the right thing in all situations. You can do macros behave like Functions-without do/while (0).
If We redefine the macro with do{...} while (0), we'll see:
#define FOO (x) do {bar (x), Baz (x);} while (0)
Now, this statement was functionally equivalent to the former. The do ensures the logic inside the curly-brackets executes, and the while (0) ensures that happens but once. Same as without the loop. For the above if statement, it'll be:
if (!feral) do {bar (Wolf), Baz (Wolf);} while (0);
Semantically, it ' s the same as:
if (!feral) {bar (Wolf); Baz (Wolf);
Might rejoin, why isn't just wrap the macro in Curly-brackets? Why also has the Do/while (0) logic? For example, we define the macro with curly bracket:
#define FOO (x) {bar (x); Baz (x);}
This is fine for the above if statement, but if we have below statement:
if (!feral) foo (wolf); else bin (Wolf);
The expanded code would be:
if (!feral) {bar (Wolf); Baz (Wolf);}; Else bin (Wolf);
This is a syntax error.
In conclusion, macros in Linux and other codebases wrap their logic in Do/while (0) because it ensures the macro always BEH Aves the same, regardless of how semicolons and curly-brackets is used in the invoking code.
Do {...} while (0) in macros