2016-05-30 4 views
0

私はいくつかのコードは、多くの場合、このようになっていることに気付きました:デバッグビルドとリリースビルドの間でコードを変更する必要がないようにゼロコストのassert()を使用することは可能ですか?

#ifdef DEBUG 
assert(i == 1); 
#endif //DEBUG 

、あなたはこれらがあなたの生のコードの周りに座ってのいくつかのブロックを有することができます。各ブロックを書き出すことは面倒で面倒です。 DEBUGフラグが指定されていない場合、ゼロコストのアサートを取得するために

#ifdef DEBUG 
auto debug_assert = [](bool expr) { 
    assert(expr);  
}; 
#else //DEBUG 
void debug_assert(bool expr) {} 
#endif //DEBUG 

:このような

auto debug_assert = [](auto expr) { 
#ifdef DEBUG 
assert(expr); 
#endif //DEBUG 
}; 

か何か:

このような機能を持つことがもっともらしいだろうか? (つまり、ラムダが実行されていないコードに入れられていない場合と同じ効果があり、g ++/clangコンパイラによって最適化されている必要があります)。

+7

'NDEBUG'を定義することによって' 'から' assert'を無効にすることができます... –

+1

* "コードはよくこのように見えます" * - しばしば?本当に? – IInspectable

+2

アサーションを有効にした状態で出荷するには、多くの自信と勇気が必要です。そして、あなたがディセーブル・アサートで出荷する場合、私たちはテストしたものを出荷するので、ディセーブル・アサートでテストする必要があります。これらは、提供可能なソフトウェアにとって困難な問題です。 –

答えて

5

@KerrekSBに記載されているように、<cassert>を含める前にNDEBUGと定義して、アサートを無効にすることができます。ヘッダファイルを含む前にそれが定義されていていることを確認する最良の方法は、コンパイラに引数としてそれをリストすることです(gccでそれは-DNDEBUGです)

注:assertはノーオペレーションの表現に置き換えることによって除去され、引数は評価されません(これは推奨ソリューションとは異なります)!このため、assertに副作用のある関数を呼び出さないことが最も重要です。

完全性については

#include <cstdio> 
#include <cstdlib> 

#ifndef NDEBUG 
#define assert(EXPRESSION) ((EXPRESSION) ? (void)0 : (printf("assertion failed at line %d, file %s: %s\n", __LINE__, __FILE__, #EXPRESSION), exit(-1))) 
#else 
#define assert(EXPRESSION) (void)0 
#endif 

は、あなた自身のassertスタイルのマクロは非常に一般的に行われている紹介:ここではassertを実現することができる方法です。あなたがこれを実行することをお勧めします理由のかなり多くがあります。

  • あなたが評価された式(キャッチのREQUIREを参照し、それらがどのように個々の要素への発現を分解するために式テンプレートを使用し、それらを文字列化に関する詳細な情報を含めますあなたは、例外をスローする開発者を郵送、ファイルへのロギング、デバッガ
  • に侵入のようなあなたも、リリースに式を評価したい、プログラムをINGのexit()以外のアクションをやりたい)
  • は以下であるのビルドエラーを起こす可能性は全くありません。(結局のところ、副作用がなければ、コンパイラで取り除くことができます最適化、およびそれがない場合は、あなただけの特異なバグを回避)
  • というように、というように(あなたのアイデアを持っている場合、あなたがコメントを投稿することができ、私は答えにそれを追加します)
関連する問題