TrickDiary このページをアンテナに追加 RSSフィード Twitter

2010-10-25

[][][][] 「Boost.勉強会 #3 関西」で「エラーハンドリング」の発表をしてきました。

発表資料等については http://d.hatena.ne.jp/youandi/20101023/p1 とか http://d.hatena.ne.jp/faith_and_brave/20101025/1287979418 あたりを漁ってください。

発表について

  • 前回の反省から今回は早めに動き出していたものの、発表内容で欲をかき過ぎたせいでいろいろ失敗してしまいました。
  • 資料作成に手間取っていたのとどのみち発表時間枠的に無理だと途中で判断し断念しましたが、本当は assert の密度と同じ密度でその続きもやりたかったです。
  • 顔文字はほぼ全てのページに挿入する予定でしたが、これも時間の都合で断念。
  • 寝不足のせいでリスナーとしてもせっかくああいう場で生で聴いてるのにいろいろ台無し。
  • 私が RedBull で買収して発表順を代わって頂いた方も実はその直前まで私の隣で資料を作成していました。

懇親会

  • お店に向かう列の最先頭グループにいたあんどちんさん( @ )はお店を直前にしたところで、別にお店に吸われてしまいました。
  • 我が妹( @ )に絡みに行こうとしたら良い場所が無かったのでとりあえず近くのしばやん( @ )のところへ行ったら、しばやんが超饒舌で、会話してるともの凄く喉が渇きました。
  • しばやんに手持ちのメイドさんが出てくるお店のカードを沢山見せてもらいました。なんであんなに沢山のお店のカードを持っているのか意味が分かりません。
  • 本当の兄弟なの?ってぐらい、しばやんは某変態のお兄さんに雰囲気がなんか似てました。
  • You&I さん( @ )が bleis さん( @ )を呼ぶ時に「おい! イケメンッ! イケメンッ!」って叫んでるのがもの凄く怖かったです。日頃、You&I さんにパシらされてる bleis さんを想像させるような呼び方でした。

はじめてのグリーン車

  • 添乗員がちょろちょろしててウザかった。
  • なんかおしぼりもらえた。
  • やっぱり確実にコンセントを利用できるのはいい。
  • 席が広めでその分乗員を減らさなければならないんだしグリーン車分の料金は、まぁ、仕方がないのかなぁと。
  • でも、一番のグリーン車の良さはその値段の高さから乗客がフィルターされてその分マナーの悪い乗客が居て不愉快な思いする可能性が下がることなんじゃないかなぁと思ったり。

UQ WiFi & UQ WiMAX

  • UQ WiFi は駅では比較的まともだったけど、新幹線の中では接続が安定せずダメダメでした。
  • それよりエリア内であれば UQ WiMAX新幹線の走行中であっても余裕で使えました。

  • MacBook Air やら kindle やら ブギーボード を見せてもらいました。本当、この手のイベントは新ガジェットを見せびらかしたい側とチェックしたい側の利害が一致してすばらしいですね。

デフォルトの名無しさんデフォルトの名無しさん 2010/10/31 09:05 公開されている error.handling.pptx より:
> エラーハンドリングを真面目にやると必ずエラー情報はツリー構造を形成させる必要がある。

これが字面どおりで正しいとすると、ツリー構造を形成しない現状の
エラー情報(戻り値あるいは例外など)に基づくエラーハンドリングはすべて
真面目にやっていないことになってしまいます。ほんとうにそうでしょうか?

何か具体的なアプリケーションでそういった情報を形成しないと望まれる処理が
できないということはあるかもしれませんが、あまりはっきりと想像は
できません。できればエラー情報をツリー構造にする必要に迫られた例を挙げて
もらえないでしょうか?

wraith13wraith13 2010/11/03 19:56 簡単に例をあげると「絶対に実行する必要のある処理が複数存在する場合」です。

問題を許容できるかどうかの話でもあるのですが、ツリーエラーモデルを採用せずシングルエラーモデル(あるいはその派生であるスタックエラーモデル)を採用すると次の問題を受け入れなければなりません。

・処理ブロック(≒tryブロック)内においてエラーが発生すると後続の処理は必ず中断される。(そのほうが望ましい状況もあれば、それだと困る状況もある)
・エラー処理中にさらにエラーが発生した場合はダブルフォールトによりプログラム全体が墜ちる。

...「エラー==例外」を前提としましたが、例外以外の形のエラーであれ、シングルエラーモデルを採用する限り多少形が変わることはあっても同根の問題が付きまとうことになります。
もちろん、これらの問題は工夫により若干低減させることは不可能ではないですが、本質的にこれらの問題を解決するにはツリーエラーモデルを採用するかエラーハンドリングを放棄する必要があります。

シングルエラーモデルはコンピュータのリソースが非常に貧弱であった頃には望ましいモデルであったんでしょうけど、現状のコンピューティング環境で未だにそれを引きずっているのは嘆かわしいことのように思います。

デフォルトの名無しさんデフォルトの名無しさん 2010/11/03 23:22 お返事ありがとうございます。ただ、2点の疑問について、すいませんが
どちらも解消されませんでした。

> ・処理ブロック(≒tryブロック)内においてエラーが発生すると後続の処理は必ず中断される。(そのほうが望ましい状況もあれば、それだと困る状況もある)

これが問題であるというのがそもそもわかっていません。

たとえば割り算が必要なところで 0 割りを検出した場合など、中断しないと
割り算の結果に依存する後続の処理は不可能です。例外はこのような場合に
中断したいと言う要求に直接答えるものになります。これでは困ると言うのなら
0 で割るかわりに行うべきことが仕様として決まっていなければならなくて、
その場合はそもそも割る数が 0 であるという事象が例外とならず、
仕様どおりの動作を続ければよいだけです。

おそらく想定している状況がまるで違うと思うので、やはり具体的な例が
欲しいです。

> ・エラー処理中にさらにエラーが発生した場合はダブルフォールトによりプログラム全体が墜ちる。

現状の C++ であればスタック巻き戻し中のデストラクタで発生する例外に
よって terminate() されてしまうことを指すものと思いますが、これは
そもそも失敗するデストラクタという点に問題があるのであって、エラー情報が
シングルだろうがツリーだろうが関係ないように思います。

こちらについても、エラー情報のデータ構造を変更することで問題が解決される
具体的な例が欲しいところです。

wraith13wraith13 2010/11/10 00:25 >たとえば割り算が必要なところで 0 割りを検出した場合など、中断しないと割り算の結果に依存する後続の処理は不可能です。

複数の値を計算する場合、問題の生じた値だけ N/A や Error とでも表示し、エラーの発生しなかった値だけでも正常に表示してくれたほうが普通は望ましいと思います。(→フェイルソフト)


>これはそもそも失敗するデストラクタという点に問題があるのであって、

それ、奴隷の発想ではないですか? 正確には「失敗する可能性のある処理をデストラクタで実行するのが悪い」んじゃなくて、本来は「失敗すると困ることになるデストラクタが悪い」んじゃありませんか?
RAII の観点からも「失敗する可能性のある処理をデストラクタで実行するな」なんて条件はとても飲めません。※
で、別に trickerr.h のようなものを利用すれば別にデストラクタで失敗するような処理を実行しても問題ないんですよ。そんな馬鹿馬鹿しい制限を受け入れなくていいんですよ。

※例えば、I/O関連のクラスであればまだ出力していないバッファ/キャッシュに残ってるデータをデストラクタでフラッシュすることになり、
 そのフラッシュに失敗した場合はデータの損失を意味するのでエラーは必ず全て呼び出し元へ伝える必要があります。

>具体的な例が欲しいところです。

繰り返しますが問題を許容できるかどうかの話でもあり、別段、特殊な事例などではなく先に挙げた「絶対に実行する必要のある処理が複数存在する場合」は普通に転がってるんですよ。
ただ、問題を許容してしまっている視点のまま、先ほどのゼロ除算やデストラクタのようにその問題でありきで本来迂回しなくていいところでわざわざ遠回りしておいて「ほら! 目的を達成できた! 問題なんてないじゃないか!」ってなってるだけかと。

# その視点を変えてくれないことにはいくら具体例を挙げても「ほら! 目的を達成でき(略」って、なっちゃいますし逆に視点を変えて頂ければ恐らく今度は自明になって例を挙げたり説明なんてする必要がなくなるんじゃないかと。

デフォルトの名無しさんデフォルトの名無しさん 2010/12/01 02:19 反応が遅くなってしまってすいません。

視点が違うようだというのはわかりました。例のスライドの記述が
気になったのは、その違う視点の片方(道化師さんのほう)が一方的に
「真面目」だとされているようだったから、かと思います。

思うに、単に2つの視点があるというだけでどちらが真面目だとかいうもの
ではないと思うのです。(一方から見れば一方は前提が違うもので、条件付で
無視できてしまう、ということです。)

僕の視点は、エラー発生した場合は後続の処理がエラーを無視して継続される
ようなことがあってはならないというもの、つまり「フェイルファスト」を
基本とするものと言えるかと思います。 C++ の例外や二重例外による
terminate() はこちらでしょう。


ある失敗する可能性にある処理と、後続の処理との間に依存関係が無い
(後続の処理が先行する処理の成功を前提としない)こと、追加の
オーバーヘッドを受け入れること、を表明する手段を言語側に用意すれば、
例外を保留するという形で↓の問題について道が開けたりする、かも
しれません。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#219

例外を保留するということ自体は C++0x ですでに std::future などの
マルチタスクサポート関連の部分に見られるようです。ツリー状のエラー情報
という概念はここらへんと絡めていくと自然に説明できる、かもしれません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/wraith13/20101025/1288015597