マクロを定義するときの do while(0) の使用は何ですか?

セミコロンを続けて、関数のように見せて動作させることができます。また、if/else 句でも適切に機能します。

while(0) がなければ、上記のコードは動作しません

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

マクロの後のセミコロンがelse句を「食べる」ため、上記はコンパイルさえしません.


複数のステートメントを 1 つのマクロにグループ化できます。

次のようなことをしたとします:

if (foo) 
    INIT_LIST_HEAD(bar);

do { ... } while (0); をカプセル化せずにマクロを定義した場合、上記のコードは

に展開されます。
if (foo)
    (bar)->next = (bar);
    (bar)->prev = (bar);

foo が成り立つ場合、最初のステートメントのみが実行されるため、これは明らかに意図したものではありません。 2 番目のステートメントは、foo が成立するかどうかに関係なく実行されます。

編集:http://c-faq.com/cpp/multistmt.html および http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html での詳細な説明#セミコロンを飲み込む