C multi-line macro: do/while(0) vs scope block
CMacrosMultilineC Problem Overview
> Possible Duplicates:
> What’s the use of do while(0) when we define a macro?
> Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
> do { … } while (0) what is it good for?
I've seen some multi-line C macros that are wrapped inside a do/while(0) loop like:
#define FOO
do {
do_stuff_here
do_more_stuff
} while (0)
What are the benefits (if any) of writing the code that way as opposed to using a basic block:
#define FOO
{
do_stuff_here
do_more_stuff
}
C Solutions
Solution 1 - C
Andrey Tarasevich provides the following explanation:
[Minor changes to formatting made. Parenthetical annotations added in square brackets []
].
> The whole idea of using 'do/while' version is to make a macro which will
> expand into a regular statement, not into a compound statement. This is
> done in order to make the use of function-style macros uniform with the
> use of ordinary functions in all contexts.
>
> Consider the following code sketch:
>
> if (foo
and bar
are ordinary functions. Now imagine that you'd
> like to replace function foo
with a macro of the above nature [named CALL_FUNCS
]:
>
> if ({
and }
) the code will no longer compile, because the 'true'
> branch of if
is now represented by a compound statement. And when you
> put a ;
after this compound statement, you finished the whole if
> statement, thus orphaning the else
branch (hence the compilation error).
>
> One way to correct this problem is to remember not to put ;
after
> macro "invocations":
>
> if (
> do {
> func1(x);
> func2(x);
> func3(x);
> } while (0)
>
> Now this code:
>
> if (CALL_FUNCS
and the first version in your message. I didn't put a
> ;
after } while (0)
. Putting a ;
at the end of that definition
> would immediately defeat the entire point of using 'do/while' and make
> that macro pretty much equivalent to the compound-statement version.
>
> I don't know why the author of the code you quoted in your original
> message put this ;
after while (0)
. In this form both variants are
> equivalent. The whole idea behind using 'do/while' version is not to
> include this final ;
into the macro (for the reasons that I explained
> above).