What's the use of do while(0) when we define a macro?

CMacrosLinux Kernel

C Problem Overview


> Possible Duplicates:
> Do-While and if-else statements in C/C++ macros
> do { … } while (0) — what is it good for?

I'm reading the linux kernel and I found many macros like this:

#define INIT_LIST_HEAD(ptr) do { \
	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)

Why do they use this rather than define it simply in a {}?

C Solutions


Solution 1 - C

You can follow it with a semicolon and make it look and act more like a function. It also works with if/else clauses properly then.

Without the while(0), your code above would not work with

if (doit) 
   INIT_LIST_HEAD(x);
 else 
   displayError(x);

since the semicolon after the macro would "eat" the else clause, and the above wouldn't even compile.

Solution 2 - C

It allows you to group several statements into one macro.

Assume you did something like:

if (foo) 
    INIT_LIST_HEAD(bar);

If the macro was defined without the encapsulating do { ... } while (0);, the above code would expand to

if (foo)
    (bar)->next = (bar);
    (bar)->prev = (bar);

This is clearly not what was intended, as only the first statement will be executed if foo holds. The second statement would be executed regardless of whether foo holds.

Edit: Further explanation at http://c-faq.com/cpp/multistmt.html and http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon

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
QuestionamazingjxqView Question on Stackoverflow
Solution 1 - CSPWorleyView Answer on Stackoverflow
Solution 2 - CrodionView Answer on Stackoverflow