http://bytes.com/groups/c/219859-do-while-0-macro-substitutions
アンドレイTarasevich:
行う「を使用しての全体的なアイデア/ while 'のバージョンは、 というマクロをコンパイルするのではなく、通常のステートメントに展開することです。これは、 の機能スタイルのマクロを、すべてのコンテキストで通常の関数を で使用するようにするために行われたものです。
は、次のコードスケッチ 'FOO' と 'バー' の通常の関数です
if (<condition>)
foo(a);
else
bar(a);
を考えてみましょう。今、あなたのマクロは(単に「{」と「}第二のアプローチ に従って定義されている場合は、上記の自然
今
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
のマクロと関数「foo」を交換したいと だろうと想像します')'の '真の' ブランチが複合文で表現されるようになったため、コードはコンパイルされなくなりました。そしてあなたは を入れて ';'この複合ステートメントの後で、 ' 'の文全体を終了し、 'else'ブランチを孤立させます(コンパイルエラー)。
この問題を解決する1つの方法は、 ';' マクロ「呼び出し」
if (<condition>)
CALL_FUNCS(a)
else
bar(a);
後これは、コンパイルと期待どおりに動作しますが、これは一様ではないでしょう。 より洗練されたソリューションは、マクロが複合語ではなく通常の ステートメントに展開されていることを確認することです。それを達成するための一つの方法は、
#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0)
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
は問題なくコンパイルされますさて、このコードを次のように にマクロを定義することです。
しかし、私の定義 のCALL_FUNCS
とあなたのメッセージの最初のバージョンとの間には、小さいながらも重要な違いがあります。私は} while (0)
の後に ;
を入れなかった。;
をその定義の最後に置くと、 はすぐに 'do/while'を使用する点全体を無効にし、 というマクロを複合文のバージョンとほぼ同等にします。
元の メッセージで引用したコードの作成者がwhile (0)
の後にこの;
を入れた理由がわかりません。この形式では、両方の変種は 相当です。 'do/while'バージョンの背後にある全体のアイデアは にはありません(上記の を説明した理由のために)この最後の;
をマクロに含めてください。
重複:http://stackoverflow.com/questions/923822/およびhttp://stackoverflow.com/questions/154136/およびhttp://stackoverflow.com/questions/257418/ – sth
実際には別の方法があります物事を正しくする。 ({...})はdo()と同じことを(0)の間に行うことができます。 Ref:http://www.bruceblinn.com/linuxinfo/DoWhile.html – Nybble