エラー
来て、コーディングして、クラッシュした。 ジュリアス・セステール

- メモリ不足。
- ディスク容量不足
- 無効なファイル名である。
- 読み取り専用ファイルに書き込もうとした。
- 存在しないファイルを読み込もうとした。
- サポートされていないシステムサービスを要求した。
エラー処理の問題
伝統的なC言語によるエラーの検出と報告方法は、伝統的なものではない、 アドホックなものであり、関数によって異なる:- NULLポインタを返す。
- 0値を返す。
- 0以外のエラーコードを返す。
- errnoのチェックを要求する。
- 前の関数が失敗したかどうかをチェックするために関数を呼び出す。 関数が失敗したかどうかをチェックするために関数を呼び出すことを要求する。
このようなエラーに対処するためには、面倒なエラー処理コードを各関数呼び出しに追加しなければならない。 を追加しなければならない。エラーが起きたら、エラーから回復するコードを書かなければならない。 エラーから回復するためのコードを書かなければならない。 エラーをユーザーに報告しなければならない。ローカルで処理できないエラーは、明示的に呼び出し元に伝えなければならない。 呼び出し元に伝えられる必要がある。 errno値の長いリストは、適切なテキストに変換して表示する必要がある。 テキストに変換する必要がある。これを行うためのコードをすべて追加することは、プロジェクトのコーディングに費やす時間の大部分を費やすことになる。 さらに、新しいerrno値がランタイム・システムに追加された場合、古いerrno値はerrno値から削除される。 新しいerrno値がランタイム・システムに追加された場合、古いコードは意味のあるエラー・メッセージを適切に表示することができない。 エラーメッセージを適切に表示することができない。
優れたエラー処理コードは、そうでなければすっきりとした実装になるはずのものを、乱雑にしてしまいがちだ。 を乱雑にしてしまう。
さらに悪いことに、優れたエラー処理コードはそれ自体がエラーを起こしやすく、プロジェクトの中で最もテストされていない(したがってバグが多い)部分になりがちである。 プロジェクトの中で最もテストされていない(したがってバグが多い)部分になりがちである。 単に省略される。最終的な結果は、プログラムが予期せぬエラーに対処できず、「死のブルースクリーン」となる可能性が高い。 プログラムが予期せぬエラーに対処できなかったからである。
クイック&ダーティなプログラムには、面倒なエラー処理コードを書く価値はない。 このようなユーティリティは、刃のガードもないテーブルソーを使うようなものだ。 を使うようなものだ。
必要なのは、次のようなエラー処理の哲学と方法論である:- 標準化されている - 一貫した使い方がより有用になる。
- プログラマーがエラーのチェックを怠ったとしても、結果は妥当である。 プログラマーがエラーチェックを怠っても、結果は妥当である。
- 古いコードを新しいコードに再利用できる。 新しいエラー型に対応するために古いコードを修正する必要がない。
- 不注意で無視されるエラーがない。
- 素早くダーティな」ユーティリティを書くことができる。 を書くことができる。
- エラー処理のソースコードの見栄えを良くするのが簡単である。
Dエラー処理ソリューション
まず、エラーについていくつかの観察と仮定をしてみよう:- エラーはプログラムの通常の流れの一部ではない。エラーは エラーはプログラムの通常の流れの一部ではない。
- エラーは例外的なものであるため、エラー処理コードの実行はパフォーマンス上重要ではない。 はパフォーマンス・クリティカルではない。
- プログラム・ロジックの通常のフローがパフォーマンス・クリティカルである。
- すべてのエラーは、何らかの方法で処理されなければならない。 すべてのエラーは何らかの方法で処理されなければならない。 によって処理されなければならない。
- エラーを検出するコードは、エラーから回復しなければならないコードよりも、エラーについて詳しく知っている。 エラーから回復しなければならないコードよりも。
解決策は、例外処理を使用してエラーを報告することである。すべての エラーはすべて、抽象クラス Error.Error を生成するtoString()という純粋な仮想関数がある。string を生成する。
コードが"out of memory"のようなエラーを検出すると、"Out of memory"というメッセージとともにError 。 がスローされる。関数呼び出しスタックが巻き戻される、 ハンドラを探す。 最後にブロック が実行される。 ブロックが実行される。エラーハンドラが見つかれば、そこで実行が再開される。もし エラー・ハンドラが見つからなければ、デフォルトのエラー・ハンドラが実行され、メッセージが表示され、プログラムが終了する。 プログラムを終了する。
これは我々の基準にどう合致しているのだろうか?
- 標準化されている-一貫した使い方がより有用になる。
- これはD流であり、D言語のランタイム・ライブラリやサンプルで一貫して使われている。 ランタイム・ライブラリや例で一貫して使われている。
- プログラマーがエラーのチェックを怠ったとしても、結果は妥当なものである。 エラーのチェックを怠っても、結果は妥当なものになる。
- エラーに対するキャッチ・ハンドラが存在しない場合、プログラムはデフォルトのキャッチ・ハンドラによって潔く終了する。 プログラムは、デフォルトのエラー・ハンドラを通じて、適切なメッセージとともに潔く終了する。 を経由して優雅に終了する。
- 古いコードを新しいコードで再利用することができる。 新しいエラー型に対応するように古いコードを修正する必要がない。
- 古いコードは、すべてのエラーをキャッチするか、特定のエラーだけをキャッチするかを決めることができる、 残りは上方に伝搬する。いずれにせよ エラー番号とメッセージを関連付ける必要はなくなる。 が常に供給される。
- 不注意で無視されるエラーはない。
- エラー例外は何らかの方法で処理される。エラー例外は何らかの方法で処理される。 エラーを示すNULLポインタが返され、その後にそのNULLポインタを使おうとするようなことはない。 そのNULLポインターを使おうとすることはない。
- クイック&ダーティな」ユーティリティは、それでもエラーを正しく処理することができる。 を書くことができる。
- クイック&ダーティなコードは、エラー処理コードを書く必要はない。 エラーをチェックする必要もない。エラーはキャッチされる、 適切なメッセージが表示され、プログラムは優雅にシャットダウンされる。 すべてデフォルトで行われる。
- エラー処理のソースコードを見栄え良くするのは簡単だ。
- try/catch/finally文は、エンドレスな次のような文よりもずっときれいに見える。 if (error) goto errorhandler; statements.
- エラーはプログラムの通常の流れの一部ではない。エラーは は例外的で、異常で、予期せぬものである。
- D例外処理はまさにそれに当てはまる。
- エラーは普通ではないので、エラー処理コードの実行はパフォーマンス上重要ではない。 の実行はパフォーマンス上重要ではない。
- 例外処理スタックの巻き戻しは比較的遅い処理である。
- プログラム・ロジックの通常のフローはパフォーマンスが重要である。
- 通常のフロー・コードでは、すべての関数呼び出しをチェックする必要はない。 通常のフロー・コードは、エラー・リターンに対してすべての関数呼び出しをチェックする必要がないので、エラーに対して例外処理を使用する方が現実的に高速である。 例外処理を使用する方が現実的に速い。
- すべてのエラーは、何らかの方法で処理されなければならない。 すべてのエラーは何らかの方法で処理されなければならない。 によって処理されなければならない。
- 特定のエラーに対応するハンドラーがない場合、そのエラーは次のように処理される。 ランタイム・ライブラリのデフォルト・ハンドラによって処理される。エラーが無視される場合 それは、プログラマーがエラーを無視するコードを特別に追加したからである。 エラーを無視するコードを追加したためである。
- エラーを検出するコードは、エラーから回復しなければならないコードよりも、エラーについて詳しく知っている。 エラーを検出したコードは、そのエラーから回復しなければならないコードよりも、エラーについて詳しく知っている。
- エラーコードを人間が読める文字列に変換する必要はもうない。 正しい文字列はエラー検出コードによって生成される。 正しい文字列はエラー回復コードではなく、エラー検出コードによって生成される。これはまた、次のことにもつながる。 アプリケーション間で同じエラーに対する一貫したエラーメッセージが生成される。
DEEPL APIにより翻訳、ところどころ修正。
このページの最新版(英語)
このページの原文(英語)
翻訳時のdmdのバージョン: 2.108.0
ドキュメントのdmdのバージョン: 2.109.1
翻訳日付 :
HTML生成日時:
編集者: dokutoku