例外Advent Calendar 途中までメモ
読んで勉強した部分のまとめ。
単語の説明
- 成功 : ある命名された処理が、その名前から期待される処理を完了できた
- 失敗 : ある命名された処理が、その名前から期待される処理を完了できなかった
- 例外的状況 : ときおり失敗する状況
- バグ : 必ず発生する失敗
- 例外 : 例外的状況から発生する失敗
- 例外処理 : 例外的な状況に対応する行為やそのための機構
- 例外機構 : いわゆるなtry/catchによる例外処理システム
- エラー値 : エラー値を用いた例外処理システム
例外安全と例外中立
- 例外処理における目的 : 例外の回復と例外の通知
- 例外の回復はとても難しい
- 例外が発生したことを上位のレイヤーに通知する
すべての処理は例外安全かつ例外中立であることが求められる。
例外安全
- 基本保証 : 単独のデータが無矛盾なく利用可能であることの保証。Exceptional C++では例として「例外が発生しても使用したオブジェクトはメモリリークを発生しないこと」を挙げている。 安全なソフトウェアを作るための保証。
- 強い保証 : 操作のロールバックを行う保証。例外が発生しても副作用をもたらさない保証で、例外回復を行う上で必須の保証。 例外回復を行うための保証。
- no-fail保証 : 必ず例外が発生しない保証。 言語や機構に要求されるための保証。
例外中立
- 例外中立 : 関数で例外を処理(または解釈したり意図的に吸収したり)しない場合、その例外を処理できる呼び出し側に伝えられるようにすること。
致命的な問題へのアプローチ
- 静的例外安全 : 実行前に例外安全の程度を知るための機構。これをサポートしているプログラミング言語はほぼない。
- 静的例外中立 : ある処理が事前に例外を発生しうるかどうかを事前に知ることが可能な機構。
- 例外設計の変更コスト : 例外安全や例外中立を事前に知ることが出来たとしても、内部処理が変わればその結果も変わる。全ての変更が連鎖的に起こってしまうので、そのままでは複雑過ぎて使い物にならない。抽象化や共通化が行えず、保守性や再利用性を著しく低下させてしまう。
プログラムの正しさ
- 事前条件 : ある処理が呼ばれる前に成立すべき条件
- 事後条件 : ある処理が呼ばれた後に成立すべき条件
- 普遍条件 : データが常に満たすべき条件
処理が失敗する可能性は、上記の3つの条件が成り立たないことの組み合わせである。
事前条件が成り立たない場合
事前条件で呼び出された全ての処理が呼び出し側から呼び出せる場合、事前条件が成り立たない責任は処理の呼び出し側にある。(perlでいうところのvalidation)
事後条件が成り立たない場合
事後条件が成り立たない責任は実装側にある。
普遍条件が成り立たない場合
不変条件が成り立たない責任は実装側(データとそれに関係する処理全ての実装を行ったもの)にある。
契約による設計
- 呼び出し側
- 義務 : 処理を適切に呼び出す(事前条件を満たす)
- 権利 : 処理が成功する(事後条件が満たされる)
- 実装側
- 義務 : 処理やオブジェクトを適切に実装する(事後条件を満たす)
- 権利 : 処理が適切に呼ばれる(事前条件が満たされる)
責任不在の失敗
契約を満たしても失敗する可能性があるため、IO操作は契約の概念が適用できない。
検査例外
Javaの検査例外
- 例外を処理の仕様として扱う
- この時の例外検査アルゴリズムは今までに述べた例外回復の考えが現れている
検査例外の目的
- 「発生しうる例外の表明」 : 発生しうる例外の種類が表明されていれば、例外回復の精度や可能性の向上が見込める。また、発生しうる例外が1つも表明されていなければ、その処理がno-fail保証を満たしていることが静的に判断可能。
- 「発生しうる例外の保証」 : ある処理が発生しうる例外として表明された例外は全て発生しうるのか、そして、それ以外の例外は決して発生しないのかを保証する機構が求められる。