重複の可能性:
C / C ++マクロのDo-Whileおよびif-elseステートメント
は{…}while(0)—何に適していますか?
Linuxカーネルを読んでいて、次のような多くのマクロを見つけました。
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
単に{}で定義するのではなく、なぜこれを使用するのでしょうか。
重複の可能性:
C / C ++マクロのDo-Whileおよびif-elseステートメント
は{…}while(0)—何に適していますか?
Linuxカーネルを読んでいて、次のような多くのマクロを見つけました。
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} 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での詳細な説明#Swallowing-the-Semicolon