web-dev-qa-db-ja.com

_DEBUG対NDEBUG

コードのデバッグセクションを指定するには、どのプリプロセッサ定義を使用する必要がありますか?

#ifdef _DEBUGまたは#ifndef NDEBUGを使用するか、それを行うより良い方法がありますか。 #define MY_DEBUG

_DEBUGはVisual Studio固有のものだと思いますが、NDEBUGは標準ですか?

126
deft_code

Visual Studioは、_DEBUGまたは/MTdオプションを指定すると/MDdを定義し、NDEBUGは標準Cアサーションを無効にします。必要に応じてそれらを使用します。つまり、デバッグコードを MS CRTデバッグ手法 と整合させる場合は_DEBUGassert()と整合させる場合はNDEBUGを使用します。

独自のデバッグマクロを定義する場合(コンパイラまたはCランタイムをハッキングしない場合)、アンダースコアで名前を開始することは避けてください。これらは予約されています。

107
Christoph

NDEBUGに依存しています。これは、コンパイラと実装全体で動作が標準化されている唯一のものであるためです(標準アサートマクロのドキュメントを参照)。ネガティブロジックは小さな読みやすさのスピードバンプですが、すぐに適応できる一般的なイディオムです。

_DEBUGのようなものに依存することは、特定のコンパイラおよびライブラリ実装の実装の詳細に依存することです。他のコンパイラは、同じ規則を選択する場合としない場合があります。

3番目のオプションは、プロジェクトに独自のマクロを定義することです。これは非常に合理的です。独自のマクロを使用すると、実装間での移植性が得られ、アサーションとは無関係にデバッグコードを有効または無効にできます。ただし、一般的には、コンパイル時に有効にするさまざまなクラスのデバッグ情報を持たないようにすることをお勧めします。これにより、おそらくわずかな利点でビルド(およびテスト)する必要がある構成の数が増えます。

これらのオプションのいずれかを使用して、プロジェクトの一部としてサードパーティのコードを使用する場合、使用する規則を認識する必要があります。

40
Adrian McCarthy

NDEBUGは標準ですか?

はい、C89、C99、C++ 98、C++ 2003、C++ 2011、C++ 2014標準のセマンティック「デバッグなし」の標準マクロです。標準には_DEBUGマクロはありません。

C++ 2003標準は、「17.4.2.1ヘッダー」の「ページ326」でリーダーを標準Cに送信します。

NDEBUGは、これが標準Cライブラリと同じであるため、類似しています。

C89(Cプログラマーはこの標準を標準Cと呼びました)では、「4.2 DIAGNOSTICS」セクションで

http://port70.net/~nsz/c/c89/c89-draft.html

NDEBUGが含まれているソースファイルのポイントでマクロ名として定義されている場合、assertマクロは単に

     #define assert(ignore) ((void)0)

Visual Studioで_DEBUGマクロの意味を見ると、 https://msdn.Microsoft.com/en-us/library/b0084kay.aspx が表示されます。このマクロ言語ランタイムライブラリバージョンの選択によって自動的に定義されます。

38
bruziuz

マクロNDEBUGは、assert()ステートメントがアクティブかどうかを制御します。

私の見解では、これは他のデバッグとは別のものです。そのため、NDEBUG以外の何かを使用して、プログラム内のデバッグ情報を制御します。使用しているものは、使用しているフレームワークによって異なります。システムごとに有効化マクロが異なり、適切なものを使用します。

フレームワークがない場合は、アンダースコアなしで名前を使用します。それらは「実装」に留まる傾向があり、名前の衝突に関する問題を回避しようとしています-名前がマクロの場合は二重です。

13

一貫性を保ち、どちらを選んでも構いません。また、何らかの理由で特定のDEBUG識別子を使用して別のプログラムまたはツールと相互運用する必要がある場合は、簡単です

#ifdef THEIRDEBUG
#define MYDEBUG
#endif //and vice-versa
6
Earlz

残念ながら、「DEBUG」は非常に過負荷です。たとえば、リリースビルド用に常にpdbファイルを生成して保存することをお勧めします。これは、-Zxフラグの1つと-DEBUGリンカーオプションを意味します。 _DEBUGは、mallocやfreeの呼び出しなど、ランタイムライブラリの特別なデバッグバージョンに関連しています。その後、NDEBUGはアサーションを無効にします。

3
James