assert
マクロにデバッグ構成でのみ役立つことを実行させるのが一般的な方法であるのはなぜですか?不変条件をテストし、コーディングのバグを検出するために存在する場合、本番ソフトウェアで同じ大きなブームを実行する方が簡単ではないでしょうか。
__ASSERT_ALWAYS
私はS60のバックグラウンドを持っていて、とが存在します。__ASSERT_DEBUG
後者は。と同等assert
です。
アサートは、決して発生してはならないものに対して行われます。つまり、発生した場合は、修正する必要のあるコードのバグがあります。リリースはバグがないと「想定」されているビルドであり、ユーザーのアサーションを使用してアプリケーションを強制終了することは、他の障害のある動作と同じくらい悪いことです。
アサーションコストをチェックします。最終製品には存在したくない余分な操作があります。アサーションが常に機能する場合、人々は「パフォーマンスを損なうことのないように」アサーションの使用を減らすでしょう。そして、私を信じてください、余分なチェックがパフォーマンスを殺すと考えて、それを避けるだろう多くの人々がそこにいます。これらは、実際にもっとassertを使用しなければならないのと同じ人々です!
より重要な理由は、assert
失敗した場合、プログラムを中止するだけであるということです。エンドユーザーにとっては何の有用性もありません(おそらくセキュリティを除いて、予期しないデータでコードを実行することを避けるためですが、実際のエラーチェックによって処理する方が間違いなく優れています)。プログラムを実際にメッセージで終了させたり、何か便利なことをしたりしたい場合は、独自のアサーションを作成する必要があります。その場合はもちろん、リリースモードのままにすることもできます。
最後に、アサーションはバグ、特に隠れたバグを見つけるのに役立ちますが、ソフトウェアの実行では、実際には発生しない可能性があります。次のコードを想像してみてください。
struct X
{
// other stuff
int stage;
};
X x;
... do some stuff
assert(x.stage == STAGE_2);
x.stage = STAGE_3; // go to next stage
... do more stuff
このような例では、ロジックはx
にあるべきだと言っていますSTAGE_2
。そうでない場合、それはバグです。ただし、アサーションを削除して修正し、先x.stage
に進むと、バグはそれほど深刻ではないことが期待されます。このような場合、エンドユーザーはこれに気付かずに実際に作業を続けることができます。リリースモードも維持assert
している場合は、目に見える効果がなかったバグに対してアプリケーションを強制的に終了させます。
実際には、ソフトウェアのアップデートを常に入手しており、バグが修正されていると彼らは主張しています。それらのいくつかは、確かにassert
キャッチしたであろうバグです。しかし、エンドユーザーとしてのあなたは何の問題もなく、それらのせいで邪魔されなかったことに実際に満足していましたassert
ね。
文化的なことだと思います。本番コードでこの種のチェックを削除することを支持する議論は次のようになります。
実行に対する議論は次のとおりです
個人的には、テストされたとおりに構築されたソフトウェアを出荷し、主張します。しかし、多くはあなたの顧客ベースとあなたがリリースをどのようにスケジュールしたいかに依存します...
この記事は一読の価値があります:-http://www.martinfowler.com/ieeeSoftware/failFast.pdf
しかし、ソフトウェアを顧客に展開するときはどうでしょうか。構成ファイルにタイプミスがあるという理由だけでアプリケーションがクラッシュすることは望ましくありません。この恐れに対する1つの反応は、現場での主張を無効にすることです。
そうしないでください!顧客のサイトで発生したエラーがテストプロセスを通過したことを忘れないでください。あなたはおそらくそれを再現するのに苦労するでしょう。これらのエラーを見つけるのは最も困難であり、問題を説明する適切に配置されたアサーションを使用すると、数日間の労力を節約できます。
もう1つ、C ++では、BOOST_ASSERTを使用して、アサーションの失敗時に例外をスローするように設定できます。これにより、アサーションの失敗の処理と回復がさらに便利になります。これをMadExceptと組み合わせて使用することで、フィールドでのアサートの失敗を、完全なコールスタック、スクリーンショット、whathaveyouを使用して、ユーザーがバグトラッカーに簡単に投稿できるようにします。
assert
明示的にオフにしない限り機能します。「リリース」ビルドであっても、(通常は)オフにする理由はなく、私が提供したリリースされたコードのほとんどはassert
アクティブになっています。
オフにする主な理由はパフォーマンスです。この場合、パフォーマンスが重要な関数で、次のように非常にローカルでオフにします。
#ifdef TURNOFFCRITICALASSERTS
#define NDEBUG
#include <assert.h>
#endif
// Function with critical code here...
#undef NDEBUG
#include <assert.h>
これは、C標準委員会assert
が使用するように設計された方法です。NDEBUG
一般に、このようにローカル以外で定義するべきではありません。