エラーのチェックと処理を改善するにはどうすればよいですか?


13

最近、私は適切なチェック量と適切な方法とは何かを理解するのに苦労しています。

これに関していくつか質問があります。

エラー(不正な入力、不正な状態など)をチェックする適切な方法は何ですか?エラーを明示的にチェックするか、最終コードから最適化できるアサートなどの関数を使用する方が良いでしょうか?とにかくほとんどの状況で実行されるべきではない多くの余分なコードでプログラムを乱雑に明示的にチェックしたい気がします-そして、ほとんどのエラーは言うまでもなく打ち切り/終了の失敗に終わります。中止するために、明示的なチェックで関数を混乱させるのはなぜですか?私はアサートとエラーの明示的なチェックを探しましたが、どちらを行うべきかを本当に説明するものはほとんど見つかりませんでした。

ほとんどの人は、「アサートを使用して論理エラーをチェックし、明示的なチェックを使用して他の障害をチェックします」と言います。しかし、これは私たちをそれほど遠くに連れて行っていないようです。これが実現可能であると言えますか:

Malloc returning null, check explictly
API user inserting odd input for functions, use asserts

これにより、エラーチェックが改善されますか?他に何ができますか?私は本当に、より良い「プロフェッショナルな」コードを改善し、書きたいと思っています。


3
良い質問ですが、姉妹サイト(プログラマー?)のいずれかに適していると思います。

おかげで、確信が持てませんでした。それはかなりコードに関連していたので、SOは大丈夫だっただろうと思いました。
アノン

3
簡単な答えは、「例外が発明された理由です。より良い言語を入手してください。」です。
-DeadMG

1
@DeadMG:setjmp/ longjmpはCで使用できるため、新しい言語は必要ありません。
user786653

3
@DeadMG:Cエラーチェックを正しく取得できない人は、C ++例外処理を正しく取得できなくなる可能性があります...-
コーダー

回答:


4

違いを判断する最も簡単な方法は、コンパイル時にエラー状態が発生するか実行時にエラー状態が発生するかを判断することです。問題が何らかの形で間違った関数を使用するプログラマーである場合、問題に注意を引くためにそれをアサートしますが、修正が呼び出しコードにコンパイルされると、それ以上チェックすることを心配する必要はありません。メモリ不足やエンドユーザーの不適切な入力などの問題はコンパイル時に解決できないため、チェックインのままにしておきます。


2

自分のコマンドで100%になっいないもの(最後のチェック後に変更されている可能性があります)はいつでもチェックしてください。また、開発中も自分を信用しないでください!;-)

Okokok ... "anything"は、異常なアボートを引き起こすようなものや、アプリケーション/システムにすべきでないことをさせるものをチェックするものとして読むことを意図してます。

深刻になるために、最後の文の最後の部分は、主要な問題を指しているため、不可欠です。

安定したシステムを構築したい場合は、システムが何をすべきかではなく、そのような必須のことをできるようにするために、「すべきではない」場合でも、すべきでないことに注意する必要ありますコード"。


1
「すべてをチェックする」ための+1。私はコードの乱雑さの議論を買いません:どんなプログラマーでもエラーチェックと実際のロジックを区別できるはずです。
stijn

2

エラー処理の要点は、問題をキャッチするかどうか、どのようにキャッチするかではありません。それについて学んだ後にすることの方が多い

まず、下位メソッドによって返されるエラーが1つでも処理されない理由はありません。また、エラーと例外は、戻り値またはすべてのtry / catch以上のものです。

  1. 投げて捕まえるだけでは不十分です。
    これを参照してください:著者は、キャッチするだけで何もしないことで例外が抑制される可能性があり、十分なダメージを取り消さない限り、コードをそのようにするよりも悪いと説明しています。同様に、ファイルのオープンまたは読み取りエラーがあるときに「ログ」ステートメントを書き込むだけで、その理由を見つけるのに役立つ場合がありますが、プログラムが終了するまでに、データが破損する可能性があります。私は多くのトライ/キャッチを持っていると言うだけでは不十分です-彼らが本当に何をするかを知ることはより重要です!

  2. 試行錯誤を乱用しないでください。
    時々-怠け者や素朴なプログラマーは、十分なtry / catchを書いた後、仕事が終わって簡単だと思います。多くの場合、単にすべてをダンプするのではなく、修正アクションを適用して再開することが最善です。これができない場合は、どのレベルで戻る必要があるかを判断する必要があります。コンテキストと重大度に応じて、キャッチネストを慎重に設計する必要があります。例- これこれを参照

  3. 責任者を定義します。
    最初にすべきことの1つは、ルーチン自体に与えられた入力が受け入れられない(またはこれまで処理されていない)シナリオであるか、環境(システムの問題、メモリの問題など)による例外であるか、またはこの状況は、アルゴリズムの結果から生じる完全に内部的なものです。すべての場合-戻りたいレベルまたは実行したいアクションは大幅に異なります。この観点から、私が言いたいのは、プロダクションでコードを実行するとき、abort()を作成してプログラムを終了するのは良いことですが、すべての小さなことではありません。メモリーの破損やメモリー不足を見つけた場合、最善を尽くした後でも物事は死ぬことは間違いありません。しかし、入力でNULLポインターを受け取った場合-私はしません

  4. 可能な限り最良の結果を定義し
    ます。すべてのことを例外の下で行う必要があることが非常に重要です。たとえば、私たちのケースの1つである-メディアプレーヤーが、ユーザーに再生する完全なデータがないことを発見した場合、どうすればよいでしょうか?

    • いくつかの悪い部分をスキップし、それが良いことで前進できるかどうかを確認します。
    • これが多すぎる場合は、次の曲にスキップできるかどうかを検討してください。
    • ファイルを読み取れないことがわかった場合は、停止して何かを表示します。
    • その間
    • どの状態でプレーヤーがユーザーにポップアップするか
    • いつ自力で実行する必要がありますか?
    • ユーザーにフィードバックすることを「停止」する必要がありますか
    • またはそれはいくつかのコーナーに控えめな小さなエラーノートを置くべきですか?

    これらはすべて主観的なものであり、おそらく問題を処理する方法は、私たちが取るに足らないものよりも多くあります。上記のすべては、例外の深さを構築して理解することを必要とし、さらに異なるシナリオを発展させることも可能にする必要があります。

  5. 例外が発生する前に例外をチェックする必要がある場合があります。最も一般的な例は、ゼロ除算エラーです。理想的には、そのような例外がスローされる前にテストする必要があります-そしてその場合は、最も適切なゼロ以外の値を入れて、自殺するのではなく先に進むようにしてください!

  6. 掃除。少なくともこれはあなたがしなければならないことです!関数がたまたま3つのファイルを開き、4つ目のファイルが開かない場合-言うまでもなく、最初の3つは閉じられていなければなりません。このジョブを上のレイヤーに委任するのは悪い考えです。メモリを消去せずに放置しないことを決定した場合。そして最も重要なこと-たとえあなたが例外を乗り越えたとしても、物事が通常のコースをとっていないことを上に知らせてください。

さまざまな階層またはレイヤーまたは抽象化の観点からソフトウェアの(通常の)機能を確認する方法。同じように、重大度と例外が発生し、システムの他の部分に影響を与えている範囲に基づいて例外を分類する必要があります。そのような異なる例外を可能な限り最良の方法で処理する方法。

ベストリファレンス:コードクラフトの第6章- ダウンロード可能


1

デバッグビルド中のエラーのチェックは、BAD IDEA(tm)、リリースオーバーレイでの再利用可能変数のスタック、コンパイル、ガードページの削除、計算による不審なトリックの実行、重度の関節炎を事前に計算されたシフトなどに置き換えるだけです。

リリースでもエラーチェックを使用します。次のような単純な手段に頼ることができます。

if(somethinghitthefan)
     abort();

これには非常に良い副作用があり、一度bettaテスターPCでアプリケーションがクラッシュし始めたら、バグを無視しないことは間違いありません。

イベントビューアーとログはに比べてまったくabort()役に立ちません。


exit / abort ==最悪のユーザーエクスペリエンス:理由を言わずにアプリケーションが消えるだけです
。– stijn

@stijn:abortデバッガーに侵入/ダンプを作成します。exit悪いです しかし、私__asm int 3は最も好む。
コーダー

それは事実であり、C / C ++では__asm int 3を使用してアサートを記述する傾向がありますが、少なくとも理由の説明を表示せずに、できれば行とファイルも表示するようにします。その後、少なくとも顧客は正確に何が起こったかについての情報を提供できます。
stijn

0

さまざまなことができます
1.多くのコードをオンラインで読んで同化して、それがどのように行われる
かを確認します
2. エラーの領域を見つけるのに役立つようにいくつかのデバッグツールを使用します3.不適切な割り当てによる些細なエラーに注意してください 構文エラー。
4.いくつかの悪い方のエラーが原因この.FORことができますペンそれを見つけると見つけるなど人や利用リソースに話してみてください、より複雑なものにするために困難ですプログラムで論理エラーにarrise StackOverflowのウィキペディアグーグルからの助けを得るために人。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.