20

重複の可能性:
C/C++ マクロに無意味な do/while ステートメントと if/else ステートメントがあるのはなぜですか?

以下のようなコードに出会いました:

#define ev_io_init(ev,cb,fd,events) \
do { \
  ev_init ((ev), (cb)); \
  ev_io_set ((ev),(fd),(events)); \
} while (0)

著者がここを使用する理由を知りたいですdo { } while (0)。これと違いはありますか?

#define ev_io_init(ev,cb,fd,events) { \
  ev_init ((ev), (cb)); \
  ev_io_set ((ev),(fd),(events)); \
}

ところで:コードはlibev、ev_local.hからのものです

4

3 に答える 3

31

検討if( something ) function1(); else function2();

function1()が実際にマクロである場合、を使用するだけ{ }で、使用時にセミコロンを省略する必要がありますがdo { } while(0)、実際の関数の場合とまったく同じ構文を使用できます。

(いかなる種類のブロック構造もまったく使用しないと、完全に壊れたコードが生成されるだけです。

于 2012-02-29T08:50:19.590 に答える
20

コードをループで囲むと、プリプロセッサディレクティブがif-else-constructsを「壊す」ことなく複数のステートメントを実行できるようになります。次のことを考慮してください。

#define DO_SOMETHING() a();b();c();

void foo()
{
    // This is ok...
    DO_SOMETHING();
}

void bar()
{
    // ...whereas this would trigger an error.
    if (condition)
       DO_SOMETHING();
    else
       blah();
}

else2番目の例では、3つのステートメントの後に句が続くため、if-else-constructが壊れています。正しく置換できるようにするには、の手順を。DO_SOMETHINGで囲む必要がありdo { ... } while(0)ます。

于 2012-02-29T08:49:41.357 に答える
12

Ado{}while(0)を使用すると、ループから抜け出すことができます。

do{
   expr1;
   foo();
   if ( cond )
      break;
   expr2;
   goo(); 
} while (0);

ステートメント{...}で必要なときに実行を中断できることを除いて、単純なブロックと同じです。break煩雑になる可能性のある複数のチェックがない限り、単純なコード ブロックでこれを行うことはできません。条件により、まだ一度実行されますwhile(0)

于 2012-02-29T08:46:26.253 に答える