例外処理のタイミング:概要
終了ハンドラーは、__try ステートメント ブロックがどのように終了された場合も常に実行されます。 終了の原因としては、__try ブロックからのジャンプ、制御がブロックの外に移動する longjmp ステートメント、例外処理によるスタックのアンワインドなどが考えられます。
Note
Microsoft C++ コンパイラは、setjmp ステートメントと longjmp ステートメントの 2 つの形式をサポートします。 高速なバージョンは終了処理をバイパスしますが、より効率的です。 このバージョンを使用するには、<setjmp.h> ファイルをインクルードします。 もう一方のバージョンは、前の段落で説明したような終了処理をサポートします。 このバージョンを使用するには、<setjmpex.h> ファイルをインクルードします。 高速バージョンでパフォーマンスがどの程度向上するかは、ハードウェア構成によって異なります。
オペレーティング システムは、例外ハンドラー本体を含む他のあらゆるコードを実行する前に、適切な順序ですべての終了ハンドラーを実行します。
中断の原因が例外の場合、システムは終了対象を決める前に、最初に 1 つ以上の例外ハンドラーのフィルター部分を実行する必要があります。 イベントの順序は次のとおりです。
例外が発生します。
システムは、アクティブな例外ハンドラーの階層を参照し、最も優先順位が高いハンドラーのフィルターを実行します。 これは、ブロックと関数呼び出しによって、最も後にインストールされ、最も深く入れ子になった例外ハンドラーです。
制御がこのフィルターを通過する (フィルターが 0 を返す) と、制御が通過できないフィルターが見つかるまで処理が続行されます。
このフィルターが -1 を返すと、例外が発生した場所で実行が続行され、終了も発生しません。
フィルターが 1 を返すと、次のイベントが発生します。
システムはスタックをアンワインドします。例外が発生した場所と例外ハンドラーを含むスタック フレームの間のすべてのスタック フレームがクリアされます。
スタックがアンワインドされると、スタックの各終了ハンドラーが実行されます。
例外ハンドラー自体が実行されます。
この例外ハンドラーの末尾の後ろのコード行に制御が進みます。