例外処理のタイミング:概要

終了ハンドラーは、__try ステートメント ブロックがどのように終了された場合も常に実行されます。 終了の原因としては、__try ブロックからのジャンプ、制御がブロックの外に移動する longjmp ステートメント、例外処理によるスタックのアンワインドなどが考えられます。

Note

Microsoft C++ コンパイラは、setjmp ステートメントと longjmp ステートメントの 2 つの形式をサポートします。 高速なバージョンは終了処理をバイパスしますが、より効率的です。 このバージョンを使用するには、<setjmp.h> ファイルをインクルードします。 もう一方のバージョンは、前の段落で説明したような終了処理をサポートします。 このバージョンを使用するには、<setjmpex.h> ファイルをインクルードします。 高速バージョンでパフォーマンスがどの程度向上するかは、ハードウェア構成によって異なります。

オペレーティング システムは、例外ハンドラー本体を含む他のあらゆるコードを実行する前に、適切な順序ですべての終了ハンドラーを実行します。

中断の原因が例外の場合、システムは終了対象を決める前に、最初に 1 つ以上の例外ハンドラーのフィルター部分を実行する必要があります。 イベントの順序は次のとおりです。

  1. 例外が発生します。

  2. システムは、アクティブな例外ハンドラーの階層を参照し、最も優先順位が高いハンドラーのフィルターを実行します。 これは、ブロックと関数呼び出しによって、最も後にインストールされ、最も深く入れ子になった例外ハンドラーです。

  3. 制御がこのフィルターを通過する (フィルターが 0 を返す) と、制御が通過できないフィルターが見つかるまで処理が続行されます。

  4. このフィルターが -1 を返すと、例外が発生した場所で実行が続行され、終了も発生しません。

  5. フィルターが 1 を返すと、次のイベントが発生します。

    • システムはスタックをアンワインドします。例外が発生した場所と例外ハンドラーを含むスタック フレームの間のすべてのスタック フレームがクリアされます。

    • スタックがアンワインドされると、スタックの各終了ハンドラーが実行されます。

    • 例外ハンドラー自体が実行されます。

    • この例外ハンドラーの末尾の後ろのコード行に制御が進みます。

関連項目

終了ハンドラーの記述
Structured Exception Handling (C/C++)