C multi-line macro: do/while(0) vs scope block

CMacrosMultiline

C 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:

  1. On Google Groups
  2. On bytes.com

[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(a); > else > bar(a); > > where 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 () > CALL_FUNCS(a); > else > bar(a); > > Now, if your macro is defined in accordance with the second approach > (just { 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 () > CALL_FUNCS(a) > else > bar(a); > > This will compile and work as expected, but this is not uniform. The > more elegant solution is to make sure that macro expand into a regular > statement, not into a compound one. One way to achieve that is to define > the macro as follows: > > #define CALL_FUNCS(x)
> do {
> func1(x);
> func2(x);
> func3(x);
> } while (0) > > Now this code: > > if () > CALL_FUNCS(a); > else > bar(a); > > will compile without any problems. > > However, note the small but important difference between my definition > of 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).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkrasnayaView Question on Stackoverflow
Solution 1 - CcaskeyView Answer on Stackoverflow