回答:
Visual Studioは_DEBUG
、/MTd
or /MDd
オプションをいつ指定するかを定義し、NDEBUG
標準Cアサーションを無効にします。必要に応じて、つまり_DEBUG
、デバッグコードをMS CRTのデバッグ手法とNDEBUG
一致させたい場合、およびと一致させたい場合に使用しますassert()
。
独自のデバッグマクロを定義する場合(およびコンパイラーやCランタイムをハックしない場合)、名前をアンダースコアで開始しないでください。これらは予約されているためです。
NDEBUGは標準ですか?
はい、これはC89、C99、C ++ 98、C ++ 2003、C ++ 2011、C ++ 2014標準のセマンティック「デバッグなし」の標準マクロです。_DEBUG
標準にはマクロはありません。
C ++ 2003標準では、「ページ326」の「17.4.2.1ヘッダー」でリーダーを標準Cに送信します。
そのNDEBUGは、これは標準Cライブラリと同じです。
C89(Cプログラマはこの標準を標準Cと呼びました)の「4.2診断」セクションで、
http://port70.net/~nsz/c/c89/c89-draft.html
NDEBUGがソースファイルのインクルードされている場所でマクロ名として定義されている場合、assertマクロは次のように定義されます。
#define assert(ignore) ((void)0)
_DEBUG
Visual Studio https://msdn.microsoft.com/en-us/library/b0084kay.aspxでマクロ
の意味を
見ると、このマクロは言語ランタイムライブラリのバージョンの選択によって自動的に定義されていることがわかります。
NDEBUG
コンパイラーと実装間で動作が標準化されているのはだけなので、私はに依存しています(標準のassertマクロのドキュメントを参照)。否定的な論理は小さな読みやすさのスピードバンプですが、すぐに適応できる一般的なイディオムです。
のようなものに依存すること_DEBUG
は、特定のコンパイラとライブラリの実装の実装の詳細に依存することです。他のコンパイラーは、同じ規則を選択する場合としない場合があります。
3番目のオプションは、プロジェクトに独自のマクロを定義することです。これは非常に合理的です。独自のマクロを使用すると、実装間での移植性が得られ、アサーションとは無関係にデバッグコードを有効または無効にできます。ただし、一般に、コンパイル時に有効になるデバッグ情報のクラスを変えることはお勧めしません。これは、わずかなメリットのために構築(およびテスト)する必要のある構成の数が増えるためです。
これらのオプションのいずれかを使用して、プロジェクトの一部としてサードパーティのコードを使用する場合は、それが使用する規則に注意する必要があります。
#if !defined(NDEBUG)
<-@HostileForkはあなたが意図したものではありませんか?#if
じゃない#ifdef
?
#ifdef NDEBUG
...を使用して否定的なロジックに特別な注意を払うこと#if !defined(NDEBUG)
です。それ以外の場合は、中のnをキャッチする少し難しい#ifndef NDEBUG
」
マクロNDEBUG
は、assert()
ステートメントがアクティブかどうかを制御します。
私の見解では、これは他のデバッグとは別のものなのでNDEBUG
、プログラムのデバッグ情報を制御する以外の方法を使用します。使用するフレームワークは、使用しているフレームワークによって異なります。システムごとに有効化マクロが異なり、私は適切なものを使用しています。
フレームワークがない場合は、先頭にアンダースコアを付けずに名前を使用します。それらは「実装」のために予約される傾向があり、名前の衝突の問題を回避しようとします-名前がマクロの場合は二重になります。
#if
制御されたコードを他のカテゴリに入れることと同じではありません。 おそらくそうではないassert(huge_object.IsValid());
かもしれませんが、遅いかもしれませassert(ptr != nullptr);
ん。ロギングとトレースは、少なくとも大規模なプロジェクトではおそらくアサーションとは区別されるべきだとジョナサンに同意しますが、ログやトレースをデバッグコードとして考えていません。