6

assertマクロにデバッグ構成でのみ役立つことを実行させるのが一般的な方法であるのはなぜですか?不変条件をテストし、コーディングのバグを検出するために存在する場合、本番ソフトウェアで同じ大きなブームを実行する方が簡単ではないでしょうか。

__ASSERT_ALWAYS私はS60のバックグラウンドを持っていて、とが存在します。__ASSERT_DEBUG後者は。と同等assertです。

4

4 に答える 4

14

アサートは、決して発生してはならないものに対して行われます。つまり、発生した場合は、修正する必要のあるコードのバグがあります。リリースはバグがないと「想定」されているビルドであり、ユーザーのアサーションを使用してアプリケーションを強制終了することは、他の障害のある動作と同じくらい悪いことです。

于 2012-08-02T13:13:12.973 に答える
12

アサーションコストをチェックします。最終製品には存在したくない余分な操作があります。アサーションが常に機能する場合、人々は「パフォーマンスを損なうことのないように」アサーションの使用を減らすでしょう。そして、私を信じてください、余分なチェックがパフォーマンスを殺すと考えて、それを避けるだろう多くの人々がそこにいます。これらは、実際にもっと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ね。

于 2012-08-02T13:13:26.063 に答える
6

文化的なことだと思います。本番コードでこの種のチェックを削除することを支持する議論は次のようになります。

  • コードの実行が遅くなります。
  • 最終的な実行可能ファイルが大きくなります。
  • 出荷後は、コードにバグが含まれていてはなりません。
  • プログラムが突然激しく終了し、データが失われる可能性があります。

実行に対する議論は次のとおりです

  • テストした正確なコードを発送します。
  • 現場で報告された問題のデバッグがはるかに簡単になります
  • 何を考えたいかに関係なく、出荷するコードにはバグがあります
  • 通常、パフォーマンスとサイズへの影響は最小限です。
  • プログラムが望ましくない状態にあるときに続行を試みるよりも、速く失敗する方が望ましい場合があります。

個人的には、テストされたとおりに構築されたソフトウェアを出荷し、主張します。しかし、多くはあなたの顧客ベースとあなたがリリースをどのようにスケジュールしたいかに依存します...

この記事は一読の価値があります:-http://www.martinfowler.com/ieeeSoftware/failFast.pdf

しかし、ソフトウェアを顧客に展開するときはどうでしょうか。構成ファイルにタイプミスがあるという理由だけでアプリケーションがクラッシュすることは望ましくありません。この恐れに対する1つの反応は、現場での主張を無効にすることです。

そうしないでください!顧客のサイトで発生したエラーがテストプロセスを通過したことを忘れないでください。あなたはおそらくそれを再現するのに苦労するでしょう。これらのエラーを見つけるのは最も困難であり、問​​題を説明する適切に配置されたアサーションを使用すると、数日間の労力を節約できます。

もう1つ、C ++では、BOOST_ASSERTを使用して、アサーションの失敗時に例外をスローするように設定できます。これにより、アサーションの失敗の処理と回復がさらに便利になります。これをMadExceptと組み合わせて使用​​することで、フィールドでのアサートの失敗を、完全なコールスタック、スクリーンショット、whathaveyouを使用して、ユーザーがバグトラッカーに簡単に投稿できるようにします。

于 2012-08-02T13:25:00.693 に答える
1

assert明示的にオフにしない限り機能します。「リリース」ビルドであっても、(通常は)オフにする理由はなく、私が提供したリリースされたコードのほとんどはassertアクティブになっています。

オフにする主な理由はパフォーマンスです。この場合、パフォーマンスが重要な関数で、次のように非常にローカルでオフにします。

#ifdef TURNOFFCRITICALASSERTS
#define NDEBUG
#include <assert.h>
#endif

//  Function with critical code here...

#undef NDEBUG
#include <assert.h>

これは、C標準委員会assertが使用するように設計された方法です。NDEBUG一般に、このようにローカル以外で定義するべきではありません。

于 2012-08-02T13:23:52.440 に答える