• ベストアンサー

グローバル初期化されるインスタンスからの例外をcatchする方法。

表題の通りですが、グローバルに初期化される インスタンスは、mainより前にコンストラクタが呼ばれると 聞きました。ならば、そこで例外を投げたらそれをcatchする 方法はあるのだろうか?という疑問です。 /*main.cpp*/ class GlobalInit { public: GlobalInit() {throw "これはどうしてもcatchされない?";} }globalInit; int main() { return 0; } 自分は、多分方法は無いだろうと考えているのですが、 初期化リスト内の例外はcatchできるなど、意外なところで 使えるようですので、もしかしたらとも思っています。 回答をご存知の方がいらっしゃいましたら、ご教授よろしくお願いします。 環境はXPのVC9です。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

そのままでは catch できね~って書いてあります. ちなみにここで catch できない例外は terminate() を呼び出すはず.

参考URL:
http://blogs.msdn.com/vcblog/archive/2006/10/20/crt-initialization.aspx
qatatatfds
質問者

お礼

「terminate()が呼ばれる?そんな馬鹿な。」と思ったのですが、 #include <cstdio> /*main.cpp*/ class GlobalInit { public: GlobalInit() {throw "これはどうしてもcatchされない?";} }globalInit; void terminate() { puts("terminate()"); } int main() { return 0; } おお、確かに呼ばれますね。 これが、まさに知りたかったことです。ありがとうございます。 今から、参考URLも読んでみます。 #main,winmain以外でソース以外から呼ばれるような仕組みが #あったということに驚きました。

すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.2

>ならば、そこで例外を投げたらそれをcatchする >方法はあるのだろうか?という疑問です。 「catch」とは「例外発生時の処理先を変更する」と言う事です。 main関数に入って来る前に行われる処理中に起きた例外は「デフォルトの例外の処理先」に飛ばされます。「デフォルトの例外の処理先」では、terminate()が呼ばれ、アプリが終了します。 そして、もし「ライブラリとして用意されているスタートアップルーチンが、デフォルトの例外の処理先を設定する前に、例外が起きる」と言う異常な状態が起きた場合は、terminate()も呼ばれず、いきなり「シェルの例外ルーチンか、OSの例外ルーチン」に吹っ飛びます。 シェルとは、Unix系のOSで言えばshやcshなど、Windows系で言えばCommand.comやcmd.exeやExplorer.exeなどの事です。 シェルの例外処理では、パイプやリダイレクトの後始末を行い、例外の発生をユーザーに伝えます(Windowsで言えば「一般保護例外の表示ダイアログ」がこれに相当する) OSの例外ルーチンも、例外の発生をユーザーに伝えます(Windowsで言えば「ブルースクリーン」がこれに相当する) そして、もし「OSの例外ルーチン」が「復帰不可能な例外をキャッチ」した場合には、OSは動作を停止します(Windowsで言えば「ブルースクリーンが出てハングアップ」と言う状態) また「何らかの例外ルーチン」の中で、例外トラップから復帰する前にもう一度例外が発生してしまうと「多重例外」として問答無用でCPUが停止します。 CPUが停止した場合は、リセットするか、電源を切って再投入するしか無くなります。 結局のところ「例外のキャッチ」とは「例外発生時にジャンプするジャンプアドレスが書いてあるジャンプテーブルのアドレスを書き換える」と言うだけの事なので、誰かがジャンプテーブルを書き換えてくれない限り、どうする事も出来ません。

qatatatfds
質問者

お礼

なるほど。 詳細な返答ありがとうございます。

すると、全ての回答が全文表示されます。

関連するQ&A