179

comp.lang.c++.moderated で、C++ ではデフォルトでデバッグ ビルドにのみ存在するアサーションを製品コードに保持する必要があるかどうかについての議論が進行中です。

明らかに、各プロジェクトは一意であるため、ここでの私の質問は、アサーションを保持する必要があるかどうかではなく、どの場合にこれが推奨されるか、または良い考えではないかということです。

主張とは、つまり:

  • false の場合、ソフトウェアのバグを明らかにする条件をテストする実行時チェック。
  • プログラムを停止するメカニズム (おそらく、最小限のクリーンアップ作業の後)。

必ずしも C や C++ について話しているわけではありません。

私自身の意見では、あなたがプログラマーであるが、データを所有していない場合 (ほとんどの商用デスクトップ アプリケーションがそうです)、アサーションの失敗はバグを示しているため、データを保持する必要があります。バグがあり、ユーザーのデータが破損するリスクがあります。これにより、出荷前に強力なテストを行う必要があり、バグがより目立ち、発見と修正が容易になります。

あなたの意見/経験は何ですか?

乾杯、

カール

関連する質問はこちら


応答と更新

グラハムさん、

アサーションはエラーであり、純粋で単純であるため、アサーションのように処理する必要があります。エラーはリリース モードで処理する必要があるため、実際にはアサーションは必要ありません。

そのため、アサーションについて話すときは「バグ」という言葉を好みます。それは物事をより明確にします。私にとって、「エラー」という言葉は漠然としすぎています。見つからないファイルはバグではなくエラーであり、プログラムで対処する必要があります。null ポインターを逆参照しようとするのはバグであり、プログラムは何か悪いチーズのようなにおいがすることを認識する必要があります。

したがって、ポインターはアサーションでテストする必要がありますが、ファイルの存在は通常のエラー処理コードでテストする必要があります。


少し話が逸れますが、議論の重要なポイントです。

注意点として、アサーションが失敗したときにアサーションがデバッガーに割り込む場合は、そうではありません。しかし、コードの完全な制御外にあるファイルが存在できない理由はたくさんあります: 読み取り/書き込み権限、ディスクがいっぱい、USB デバイスが取り外されているなど。制御できないため、アサーションはそれに対処する正しい方法ではありません。

カール


トーマス、

はい、私は Code Complete を持っていますが、その特定のアドバイスには強く反対します。

カスタム メモリ アロケータが台無しになり、他のオブジェクトがまだ使用しているメモリのチャンクをゼロにしたとします。このオブジェクトが定期的に逆参照するポインターをたまたまゼロにします。不変条件の 1 つは、このポインターが決して null にならないことです。その状態を維持するためのいくつかのアサーションがあります。ポインタが突然 null になったらどうしますか。それが機能することを期待して、それを if() するだけですか?

ここでは製品コードについて話しているので、デバッガーに侵入してローカル状態を検査する必要はありません。これは、ユーザーのマシンの実際のバグです。

カール

4

17 に答える 17

96

アサーションは、時代遅れにならないコメントです。それらは、どの理論的状態が意図され、どの状態が発生してはならないかを文書化します。コードが変更されてステートの変更が許可された場合、開発者はすぐに通知を受け、アサーションを更新する必要があります。

于 2009-01-08T12:21:02.377 に答える
65

Steve McConnell の Code Complete を引用させてください。アサーションに関するセクションは 8.2 です。

通常、実稼働コードでアサーション メッセージをユーザーに表示することは望ましくありません。アサーションは、主に開発および保守中に使用するためのものです。アサーションは通常、開発時にコードにコンパイルされ、本番用にコードからコンパイルされます。

ただし、同じセクションの後半で、次のアドバイスが提供されます。

非常に堅牢なコードの場合は、とにかくエラーをアサートして処理します。

パフォーマンスが問題にならない限り、アサーションはそのままにして、メッセージを表示するのではなく、ログ ファイルに書き込むようにすると思います。そのアドバイスは Code Complete にもあると思いますが、今のところ見つかりません。

于 2008-08-20T12:29:46.277 に答える
37

アサーションをオフにするとプログラムの実行速度が大幅に速くなることが測定されない限り、本番コードではアサーションをオンのままにしておきます。

より効率的であることを証明するために測定する価値がないのであれば、パフォーマンスのギャンブルのために明快さを犠牲にする価値はありません." - Steve McConnell 1993

http://c2.com/cgi/wiki?ShipWithAssertionsOn

于 2010-05-19T22:52:53.040 に答える
24

アサーションを本番環境に残すことを考えている場合でも、おそらく間違っていると考えています。アサーションの要点は、ソリューションの一部ではないため、本番環境ではオフにできるということです。これらは開発ツールであり、仮定が正しいことを確認するために使用されます。しかし、本番環境に入るときには、すでに自分の仮定に自信を持っているはずです。

そうは言っても、本番環境でアサーションをオンにするケースが 1 つあります。テスト環境で再現するのに苦労している再現可能なバグが本番環境で発生した場合は、アサーションをオンにしてバグを再現すると役立つ場合があります。有用な情報を提供するかどうかを確認します。

もっと興味深い質問は次のとおりです。テスト フェーズでは、いつアサーションをオフにしますか?

于 2014-01-20T23:06:12.603 に答える
17

アサーションは本番コードにとどまるべきではありません。特定のアサーションが製品コードで役立つ可能性があると思われる場合、それはアサーションであってはなりません。これは実行時のエラー チェック、つまり次のようにコード化されたものである必要がありますif( condition != expected ) throw exception

「アサーション」という用語は、「フィールドでは実行されない開発時のみのチェック」を意味するようになりました。

あるアサーションがフィールドに出てくるかもしれないと考え始めると、他の危険な考えも必然的に作り始めることになります。する価値のない主張はありません。「これを主張すべきかどうか」と自問してはいけません。「主張するのを忘れたことはありますか?」と自問するだけです。

于 2014-09-23T15:20:50.847 に答える
7

アサーションがパフォーマンスの問題を引き起こしていることをプロファイリングが示さない限り、それらは製品リリースにもとどまるべきだと私は言います。

ただし、これには、アサーションの失敗をある程度適切に処理することも必要だと思います。たとえば、プログラムを終了またはクラッシュさせるだけでなく、(自動的に) 開発者に問題を報告するオプションを備えた一般的なタイプのダイアログが表示される必要があります。また、実際には許可しているが、好ましくない、または望ましくないと考えられる条件に対してアサーションを使用しないように注意する必要があります。これらの条件は、コードの他の部分で処理する必要があります。

于 2008-08-20T11:08:00.047 に答える
6

私の C++ では、リリース ビルドでアサーションが失敗した場合に例外をスローすることを除いて、assert(x) に似た REQUIRE(x) を定義しています。

失敗したアサーションはバグを示しているため、リリース ビルドであっても真剣に扱う必要があります。コードのパフォーマンスが重要な場合、高レベルのコードには REQUIRE() を使用し、高速に実行する必要がある低レベルのコードには assert() を使用することがよくあります。また、サード パーティによって記述されたコードから渡されたデータ、またはファイルの破損によって障害状態が発生する可能性がある場合は、アサートの代わりに REQUIRE を使用します (ファイルが破損した場合に適切に動作するようにコードを特別に設計するのが最適ですが、いつもそれをする時間がない.)

彼らは、エンドユーザーが理解できないので、これらのアサートメッセージをエンドユーザーに見せるべきではないと言います。そう?エンド ユーザーは、デバッグに役立つスクリーン ショットまたはエラー メッセージのテキストを電子メールで送信する場合があります。ユーザーが単に「クラッシュした」と言った場合、それを修正することはできません。アサーション失敗メッセージを自分自身に自動的に送信する方がよいでしょうが、それが機能するのは、(1) あなたが制御/監視しているサーバー上でソフトウェアが実行されている場合、または (2) ユーザーがインターネット アクセスを持っていて、送信の許可を得ることができる場合のみです。バグレポート。

于 2008-11-25T17:09:59.210 に答える
4

それらを保持したい場合は、エラー処理に置き換えてください。プログラムが消えてしまうことほど悪いことはありません。特定のエラーを重大なバグとして扱うことに何の問題もありませんが、データを収集してログに記録し、アプリに望ましくない状態が発生したことをユーザーに通知することで、エラーを処理できるようになっているプログラムのセクションに転送する必要があります。終了しています。

于 2008-08-20T12:28:05.453 に答える
2

当社のデータベース サーバー ソフトウェアには、本番アサーションとデバッグ アサーションの両方が含まれています。デバッグ アサーションはまさにそれであり、プロダクション コードでは削除されます。プロダクション アサーションは、(a) 存在してはならない何らかの状態が存在し、(b) この状態から確実に回復できない場合にのみ発生します。製品アサーションは、ソフトウェアにバグが発生したか、何らかのデータ破損が発生したことを示します。

これはデータベース システムであり、潜在的にエンタープライズ クリティカルなデータを格納しているため、破損したデータを回避するためにできる限りのことを行います。誤ったデータを保存する可能性のある状況が存在する場合、直ちにアサートし、すべてのトランザクションをロールバックして、サーバーを停止します。

そうは言っても、パフォーマンスが重要なルーチンではプロダクション アサーションを避けるようにしています。

于 2008-08-20T13:06:46.127 に答える
2

他のエラーと同じように処理されれば、問題はないと思います。ただし、C でアサーションが失敗すると、他の言語と同様にプログラムが終了することに注意してください。これは通常、運用システムでは十分ではありません。

いくつかの例外があります。たとえば、PHP では、アサーション エラーのカスタム ハンドラーを作成できるため、終了するだけでなく、カスタム エラーを表示したり、詳細なログを記録したりできます。

于 2008-08-20T11:22:54.143 に答える
1

私はアサートをインライン単体テストと見なしています。開発中の簡単なテストに役立ちますが、最終的にはこれらのアサーションをリファクタリングして、単体テストで外部でテストする必要があります。

于 2012-10-27T11:39:30.160 に答える
0

コンパイル時の型チェック以外の目的でアサーションを使用することはめったにありません。ほとんどの言語は例外を処理するように構築されているという理由だけで、アサーションの代わりに例外を使用します。

私は例を提供します

file = create-some-file();
_throwExceptionIf( file.exists() == false, "FILE DOES NOT EXIST");

に対して

file = create-some-file();
ASSERT(file.exists());

アプリケーションはアサーションをどのように処理しますか? try catch私は、致命的なエラーを処理する古い方法を好みます。

于 2008-08-20T11:19:04.810 に答える
0

ほとんどの場合、Java でアサーション (assert キーワード) を使用すると、後でいくつかの製品コードを自動的に追加します。場合に応じて、ログ メッセージ、例外、または何もない場合があります。

私によると、あなたの主張はすべて、本番リリースではなく、開発リリースで重要です。それらのいくつかは保持する必要があり、他のものは破棄する必要があります。

于 2008-08-20T11:19:05.730 に答える
0

ASSERTION はエラーではなく、エラーとして扱われるべきではありません。アサーションがスローされた場合、これは、コードまたはコードを呼び出すコードにバグがあることを意味します。

プロダクション コードでアサーションを有効にしないようにするためのポイントがいくつかあります。パフォーマンスに影響を与える

ただし、アサーションを残す強い理由が 1 つあります。ASSERTION はパフォーマンスとタイミングに影響を与える可能性があり、悲しいことに、これが問題になる場合があります (特に組み込みシステムでは)。

私は製品コードにアサーションを残すことに投票する傾向がありますが、これらのアサーションの出力がエンド ユーザーに公開されないようにします。

〜イジク

于 2013-09-22T05:23:28.903 に答える
-8

アサーションはエラーであり、純粋で単純であるため、アサーションのように処理する必要があります。

エラーはリリース モードで処理する必要があるため、実際にはアサーションは必要ありません。

アサーションの主な利点は、条件付きブレークです。VC のウィンドウをドリルダウンして 1 行のコードで何かをセットアップするよりも、はるかに簡単にセットアップできます。

于 2008-08-20T11:17:52.893 に答える