- ベストアンサー
例外の種類と状況・対処法
- 例外の種類と発生する状況、対処法を詳しくまとめました。
- 例外の発生状況や対処法について、具体的なコード例や注意事項を解説しました。
- 例外の種類と状況、それぞれの対処法についてまとめました。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> マジですか!? > 具体的なところを教えてください。 VC++のmallocは、_set_new_modeと_set_new_handlerを使って、メモリの割付けに失敗した場合にユーザー定義のハンドラを呼び出すことができます。つまり、そこから例外を送出できてしまうわけです。 > そういうことを話し合いたいわけではないので それは想像が付いていますが... > 「ほぼ完全」で問題ありません。 「ほぼ」というのがどのレベルの話なのかがわかりません。 結局、議論しているのが、モジュールやクラスレベルの話なのか、(DLLを含めた)ライブラリレベルの話なのか、アプリケーションレベルの話なのか、それともOSや周辺機器などをすべて含めたシステム全体の話なのかによります。
その他の回答 (2)
- jacta
- ベストアンサー率26% (845/3158)
> そこまで詳しく状況別で解説できるほどよく御存じなのですか? そんな難しい話ではありません。 例えば、クラスやライブラリなど、それ単独では動かないような場合、どんな使い方をされるかはクライアントコードしだいになります。 その場合、各種ハンドラや別のスレッドなど、自分ではコントロールし切れない要素が出てしまうわけです。 アプリケーションであれば多少ましですが、それでも、別のプロセスによって動作を変えられる可能性も完全には否定できません。 OSの状態や周辺機器の状態までコントロールでき、ネットワークにも接続しないのであれば、完全に制御できる可能性はずっと高まります。 要はそういうことです。 > その他の全ての発生可能性を消せれば、try catch > を完全に意図通りに制御できると考えて良いでしょうか? 本当に「すべての発生可能性を消せれば」その通りです。
お礼
そういうことであればその通りでしょうが そういう概念自体であればわざわざ問答しなくても考えればわかるわけで、私が質問してる意味自体もjactaさんが回答している意味自体もなくなってしまいます。 どんなライブラリだって、常識的に考えておかしい使い方されたらおかしい結果になって然りと思いますが… 「プログラマがコントロール出来てるという前提として」なのでクライアントコード次第…という事は成り立ちません。 世に別のプロセスによって動作を変えられて、そのあらゆるパターンに対してうまく対処しきれるようなアプリケーションはどれほどあるでしょうか? その必要は、積極的にほかのアプリと関わるようなアプリケーション、あるいはそういった部分以外 基本的には考える必要ないと思っていいのではないでしょうか? 私はもっと「自分で作るアプリケーション内、あるいは自分で書いた範囲内で判断すれば少なくとも綺麗に完結出来てるようなコードを書こうとすれば」という側に近い視点での話をしたいのです。実際にコードを書こうとしてるから疑問を解決したいわけで、現実的にはどう手を打つべきかを中心に考えないと、さっぱり要領を得ません。 それで、結果として std::bad_typeid std::ios_base::failure std::invalid_argument std::range_error std::overflow_error std::underflow_error についてはご存じないのですか? 記述を見れば対処法のある程度の予想は出来るものもますが 再現コードの具体例が分からないと確信が出来ません。
補足
約二年越しでの補足となりますが これらの再現コードはいまだ分かりません。 とはいえ とりあえず今のところ 自分自身で作ってきた アプリケーションに於いて std::~ 系統の例外に「手を焼いた」ケースは std::bad_alloc含め一度もないという結果になっています。 また5件に達したら締め切らないと新規質問を出来ないという教えてgooのルールもあるので この件は「まぁそれほど心配もいらないだろう」と考え 解決とさせていただきます。
- jacta
- ベストアンサー率26% (845/3158)
まずは処理系を明確にすべきです。 > 警告C4290(http://msdn.microsoft.com/ja-jp/library/sa28fef8%28VS.80%29.aspx) > が出るので発生自体は確認できませんでした。 とのことなので、Visual Studio 2005なのでしょうか? > その他の全ての発生可能性を消せれば、try catch > を完全に意図通りに制御できると考えて良いでしょうか? 他人が作ったライブラリを一切使うことができないということになりますが、本当にそれが可能でしょうか? 規格上は、qsortやbsearchのようなコールバックを渡すもの以外は、標準Cライブラリの関数は例外を送出しないことになっていますが、VC++はmallocが例外を送出するかもしれないという反則をやっていますからね。 標準C++ライブラリの場合は、明示的に例外指定throw()がなければ、どんな例外が送出されるかはわかりません。処理系の独自ライブラリであれば、なおさらです。 それに、完全に制御しきれなければ、可能性を完全に消すことはできません。 例えば、Visual Studio 2005であれば、.NETのコードと混在しているのであれば、ThreadAbortExceptionが非同期に送出される可能性などは考えなくてもよいのでしょうか? 未定義の動作の結果、いわゆる構造化例外が発生した場合はどうでしょうか? 別のスレッドが、SetThreadContextを使うなどして、まったく関係のない処理を割り込ませた場合はどうですか? どんなにレアケースであっても、完全かどうかを議論するのであれば、考慮しなけれななりません。
お礼
>まずは処理系を明確にすべきです。 それについてはごもっともです。 VC++2008EEを現在使っていますが、そのうち新しい方へ移っていく予定です。 >本当にそれが可能でしょうか? それは分かりません。ただし、私が書いた >その他の全ての発生可能性を消せれば、try catch を完全に意図通りに制御できると考えて良いでしょうか? は、あくまでたとえです。本意は「そういう状況がもしあったら可能かどうか」ということが知りたいのです。 人の書いたライブラリに胸を張って「副作用含め完全に例外に対応できています」といえる人はいないと思います。 仕様を隅々まで見なければ言えないと思います。 現実的には、作った人自身例外を送出することがはっきりわかってるのであれば仕様書ぐらいあってもおかしくないと思いますし、それしか見れない場合はそれを信頼するしかありません。 ただ、 >mallocが例外を送出するかもしれないという反則 マジですか!? 具体的なところを教えてください。 現在は混在していないので.NETについてはその可能性はないです。 「プログラマが全部把握してて主体」になっている、という前提では、という話なので 「別のスレッドが」勝手に行動するわけではありません そのスレッドの動きもコントロールしてるとして、という前提では、という話です。 >完全かどうかを議論するのであれば、考慮しなけれななりません。 そういうことを話し合いたいわけではないので「ほぼ完全」で問題ありません。 構造化例外についてですが、それもコード側で現実的にコントロールできるような部分は対処し、普通のアプリケーションはそこまで首を突っ込むべきじゃないだろうとか、コード側では普通どうにもならないかと…という部分は無視することにします。 といっても厳密な「普通」の線引はこの宇宙の構造的に無理だと思うので、ある程度察していただけるとありがたいです。
お礼
>_set_new_modeと_set_new_handler ありがとうございます。じっくり調べておきます。 >結局、議論しているのが、モジュールやクラスレベルの話なのか、(DLLを含めた)ライブラリレベルの話なのか、アプリケーションレベルの話なのか、それともOSや周辺機器などをすべて含めたシステム全体の話なのかによります。 そこまで詳しく状況別で解説できるほどよく御存じなのですか? というか、「例外」という側面において モジュールやクラスレベルの話 ライブラリレベルの話 アプリケーションレベルの話 OSや周辺機器などをすべて含めたシステム全体の話 を明確に区切ること自体は可能なのでしょうか? OSや周辺機器がなければ実行できませんし、出来るものはアプリケーションなわけですし、ライブラリを使えば便利だと思いますし、時には自分で作るかもしれません。そしてC++なら当然モジュール・クラスはかかわらざるを得ないと思います。 加えて、分からないので質問しているために、どのレベルの話に該当し得るのかが分かりません。 当の私は、そんなに大きな話に膨らむとは全く想定していませんでしたので この際、不明瞭ならば >std::bad_allocは目を瞑るとして(コードを書くことで対処するとして) その他の全ての発生可能性を消せれば、try catch を完全に意図通りに制御できると考えて良いでしょうか? この部分は全くなしとして読んでください。 この質問での最大の目的は std::~ の上記12種類の再現コードと、再現コードはなくてもせめておおよそ十分といえるであろう対処法を確保したいというところにあります。