いくつかの説明。1つ目は一般的なもの、2つ目はパラメータ付きのCプリプロセッサマクロに固有のものです。
フロー制御
これがプレーンなCコードで使用されているのを見てきました。基本的に、それはgotoのより安全なバージョンです。それを抜け出すことができ、すべてのメモリが適切にクリーンアップされるからです。
なぜ何かgotoが良いのでしょうか?ええと、ほとんどすべての行がエラーを返す可能性があるコードがあるが、それらすべてに同じように対応する必要がある場合(たとえば、クリーンアップ後に呼び出し元にエラーを渡すことにより)、通常は、より読みやすく、if( error ) { /* cleanup and error string generation and return here */ } asます。クリーンアップコードの重複を回避します。
ただし、C ++では、この目的に例外+ RAIIがあるため、コーディングスタイルが悪いと考えます。
セミコロンチェック
関数のようなマクロ呼び出しの後にセミコロンを忘れると、引数が望ましくない方法で縮小され、有効な構文にコンパイルされる可能性があります。マクロを想像してください
#define PRINT_IF_DEBUGMODE_ON(msg) if( gDebugModeOn ) printf("foo");
それは誤って
if( foo )
PRINT_IF_DEBUGMODE_ON("Hullo\n")
else
doSomethingElse();
「他」に関連しているとみなされるgDebugModeOnのでとき、fooありますfalse正確などうなることを意図したものとは逆の、。
一時変数のスコープを提供します。
do / whileには中括弧があるため、一時変数には、エスケープできない明確に定義されたスコープがあります。
「おそらく不要なセミコロン」警告の回避
一部のマクロは、デバッグビルドでのみアクティブになります。次のように定義します。
#if DEBUG
#define DBG_PRINT_NUM(n) printf("%d\n",n);
#else
#define DBG_PRINT_NUM(n)
#endif
これを条件付きのリリースビルドで使用すると、コンパイルされます
if( foo )
;
多くのコンパイラはこれを
if( foo );
誤って書かれることが多い。したがって、警告が表示されます。do {} while(false)はこれをコンパイラーから隠し、本当にそれを示すものとして受け入れられますここで何もしないようにしたいです。
条件文による行のキャプチャを回避する
前の例のマクロ:
if( foo )
DBG_PRINT_NUM(42)
doSomething();
デバッグビルドでは、セミコロンも常用しているので、これで問題なくコンパイルできます。ただし、リリースビルドでは、これは突然次のようになります。
if( foo )
doSomething();
またはより明確にフォーマット
if( foo )
doSomething();
これは意図されたものとはまったく異なります。マクロの周りにdo {...} while(false)を追加すると、欠落しているセミコロンがコンパイルエラーになります。
OPとはどういう意味ですか?
一般に、エラー処理にはC ++の例外を使用し、マクロの代わりにテンプレートを使用します。ただし、まだマクロが必要である(トークン貼り付けを使用してクラス名を生成する場合など)非常にまれなケースや、プレーンCに制限されている場合、これは便利なパターンです。