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

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 \
  }

This question is related to c macros multiline

The answer is


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 (<condition>)
  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 (<condition>)
  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 (<condition>)
  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 (<condition>)
  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).


Examples related to c

conflicting types for 'outchar' Can't compile C program on a Mac after upgrade to Mojave Program to find largest and second largest number in array Prime numbers between 1 to 100 in C Programming Language In c, in bool, true == 1 and false == 0? How I can print to stderr in C? Visual Studio Code includePath "error: assignment to expression with array type error" when I assign a struct field (C) Compiling an application for use in highly radioactive environments How can you print multiple variables inside a string using printf?

Examples related to macros

How to use __DATE__ and __TIME__ predefined macros in as two integers, then stringify? how to use #ifdef with an OR condition? What is ":-!!" in C code? How to pass macro definition from "make" command line arguments (-D) to C source code? __FILE__ macro shows full path Where are the recorded macros stored in Notepad++? How to identify platform/compiler from preprocessor macros? What does "#pragma comment" mean? C Macro definition to determine big endian or little endian machine? How do I show the value of a #define at compile-time?

Examples related to multiline

Way to create multiline comments in Bash? How to get multiline input from user R: "Unary operator error" from multiline ggplot2 command Can a JSON value contain a multiline string PHP multiline string with PHP Pythonic way to create a long multi-line string How do I create a multiline Python string with inline variables? How do you write multiline strings in Go? Multiline TextView in Android? What is the proper way to format a multi-line dict in Python?