[解決済み】Cの複数行マクロ:do/while(0) vs スコープブロック [重複]。
質問
重複の可能性があります。
マクロを定義するときにdo while(0)を使うとどうなるのですか?
C/C++のマクロで無意味なdo/whileやif/else文があることがあるのはなぜですか?
do { ... } while (0) 何の役に立つの?
C言語の複数行マクロで、do/while(0)ループの中に入っているようなものを見たことがあるのですが。
#define FOO \ do { ♪Do_stuff_here ♪Do_stuff_here ♪Do_stuff_here ドゥモア・スタッフ } while (0)
基本的なブロックを使用するのとは対照的に、そのようにコードを書くことの利点は何ですか(もしあれば)。
#define FOO \ { \ ♪Do_stuff_here ♪Do_stuff_here ♪Do_stuff_here ドゥモア・スタッフ }
解決方法は?
アンドレイ・タラセビッチ氏は次のように説明しています。
[書式に若干の変更がありました。角括弧内に親書きの注釈を追加しました。
[]
].
do/while'バージョンを使用する全体的なアイデアは、マクロを作成することです。 は、複合文ではなく、通常の文に展開されます。これは 関数型マクロと統一するためです。 は、あらゆる文脈で通常の関数を使用することができます。
次のようなコードスケッチを考えてみましょう。
if (<condition>)
foo(a);
else
bar(a);
ここで
foo
と
bar
は普通の関数です。ここで
を置き換えることができます。
foo
を上記のような性質のマクロ [名前
CALL_FUNCS
]:
if (<condition>)
CALL_FUNCS(a);
else
bar(a);
さて、2番目のアプローチに従ってマクロが定義されている場合
(ただ
{
と
}
) は、もはやコンパイルされないでしょう。
のブランチ
if
が複合文として表現されるようになりました。そして
を置く
;
の後に、この複合ステートメントを追加すると、全体の
if
ステートメントを削除し、その結果
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'バージョンを使用する全体的な考え方は、以下の通りです。
には、この最後の
;
をマクロに組み込むことができます(理由は説明したとおりです)。
となります。)
関連
-
[解決済み】"Expected expression before ' { ' token"(トークンの前に期待される式)。
-
[解決済み】GCC Cコードで静的宣言が非静的宣言に続くことを解決するには?
-
[解決済み】 error: too few arguments to function `printDay' (C言語)
-
[解決済み】警告。この関数ではXが初期化されていない状態で使用される可能性があります。
-
[解決済み】エラー:イニシャライザー要素がロード時に計算可能でない
-
[解決済み】 「配列のイニシャライザーはイニシャライザーリストまたは文字列リテラルでなければなりません」と表示されるのですが?
-
[解決済み] 複数行の長い文字列を作成するためのPythonicな方法
-
[解決済み] マクロで無意味なdo-while文やif-else文を使っているのはなぜですか?
-
[解決済み] Rubyで複数行のコメント?
-
[解決済み] 複数行のコマンドを入力する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Connect: ソケット以外でのソケット操作
-
[解決済み】ポインタと整数の比較で警告が出る
-
[解決済み】ポインタへの代入時に互換性のないポインタ型からの初期化警告が発生した
-
[解決済み】初期化がキャストなしで整数からポインタを作成 - C言語
-
[解決済み】エラー。非スカラー型への変換を要求された
-
[解決済み】「複数の定義」「最初に定義されたのはここです」エラーについて
-
[解決済み] '{'トークンの前に期待される式
-
[解決済み】makefile:4。*** missing separator. 停止する
-
[解決済み] マクロで無意味なdo-while文やif-else文を使っているのはなぜですか?
-
[解決済み] do { ... } while (0) - 何のために良いですか?[重複]する