134

重複の可能性:
C / C ++マクロのDo-Whileおよびif-elseステートメント
は{…}while(0)—何に適していますか?

Linuxカーネルを読んでいて、次のような多くのマクロを見つけました。

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

単に{}で定義するのではなく、なぜこれを使用するのでしょうか。

4

2 に答える 2

149

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

while(0)がないと、上記のコードは機能しません

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

マクロの後のセミコロンはelse句を「食べる」ので、上記はコンパイルすらしません。

于 2009-05-29T00:09:22.077 に答える
44

複数のステートメントを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での詳細な説明#Swallowing-the-Semicolon

于 2009-05-29T00:11:47.080 に答える