2009-07-01 2 views
146

重複の可能性:私はいくつかのマルチラインCマクロを見てきました
What’s the use of do while(0) when we define a macro?
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
do { … } while (0) what is it good for?C複数行のマクロは:/やるしばらく(0)スコープブロック対

次のようなdo/while(0)ループの中にラップされています。

 
#define FOO \ 
    do { \ 
    do_stuff_here \ 
    do_more_stuff \ 
    } while (0) 

コードを書くことの利点(もしあれば)基本ブロックを使用するのではなく、その方法はどのようなものです:

 
#define FOO \ 
    { \ 
    do_stuff_here \ 
    do_more_stuff \ 
    } 
+4

重複:http://stackoverflow.com/questions/923822/およびhttp://stackoverflow.com/questions/154136/およびhttp://stackoverflow.com/questions/257418/ – sth

+0

実際には別の方法があります物事を正しくする。 ({...})はdo()と同じことを(0)の間に行うことができます。 Ref:http://www.bruceblinn.com/linuxinfo/DoWhile.html – Nybble

答えて

212

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'バージョンの背後にある全体のアイデアは にはありません(上記の を説明した理由のために)この最後の;をマクロに含めてください。

+35

オリジナルの投稿は 'comp.lang.c'で私によって作られました。 'bytes.com'は明らかに' comp.lang.c'の内容をソースを参照することなく "充当"しています。 – AnT

関連する問題