ステートメントとを除く
Microsoft 固有の仕様 →
次の構文はを除くステートメントを記述します :
__try
{
// guarded code
}
__except ( expression )
{
// exception handler code
}
解説
とを除く のステートメントを C と C++ の言語に通常プログラムの実行を終了させるイベントが発生するとコントロールを取得する対象アプリケーションを有効にする Microsoft の拡張機能です。このような例外イベントは例外を除き扱うが構造化例外処理と呼ばれる機能と呼ばれます。
関連情報についてはtry-finally ステートメント を参照してください。
例外はハードウェア ベースまたはソフトウェア ベースです。アプリケーションがハードウェアまたはソフトウェア例外から完全に回復できない場合でも構造化例外処理ではエラー情報を表示し問題の診断をアプリケーションの内部状態をトラップすることができます。これは簡単に再現できない断続的な問題に特に役立ちます。
[!メモ]
構造化例外処理ではC および C++ のどちらのソース ファイルの Win32 を使用します。ただしC++ 向けに設計されていません。コードが C++ 例外処理を使用して汎用性のあることを確認します。またC++ 例外処理は任意の型の例外処理できることよりも柔軟性があります。C++ プログラムではC++ 例外処理機構 (trycatchthrow のステートメント) を使用することをお勧めします。
__try 句で保護されたセクションの本文またはと複合ステートメントを指定します。__except 句の後の複合ステートメントで例外ハンドラーです。ハンドラーは例外が保護されたセクションの本文の実行中に発生した場合に実行される一連のアクションを指定します。実行は次のように検索されます :
保護されたセクションが実行されます。
例外が保護されたセクションの実行中に発生する実行が __except の句の後ろのステートメントから実行します。
例外が保護されたセクションの任意のルーチンの実行中に発生した保護されたセクションでは__except の 式は 評価 する式 ) 例外を処理する方法と値を評価されます。値 3 があります :
EXCEPTION_CONTINUE_EXECUTION (– 1) の例外が閉じます。例外が発生した位置で実行を継続します。
EXCEPTION_CONTINUE_SEARCH (0) の例外は認識されません。次のの優先順位のハンドラーを とを除く のステートメントを含むハンドラーをスタックにまずを検索し続けます。
(1) EXCEPTION_EXECUTE_HANDLER の例外が認識されます。__except の複合ステートメントの実行に例外ハンドラーに制御を移動し実行をブロックの後 __except 後。
の を除く の式は. の式として評価されるため一つの値条件式の演算子またはコンマ演算子に制限されます。より広範な処理が必要な場合式は上記の値 3 から 1 にそのルーチンを呼び出すことができます。
各アプリケーションは独自の例外ハンドラーが見つかったことができます。
これは __try のステートメントに進むは無効外部にジャンプする留めるための 1 種類の有効です。例外ハンドラーはプロセスが とを除く ステートメントの実行の途中で終了すると呼び出されます。
詳細についてはサポート技術情報の文書を参照してください Q315937: 方法 : Visual C++ アプリケーションにスタック オーバーフローのトラップしてください。
__leave のキーワード
__leave のキーワードは try-except のステートメントの保護されたセクション内でのみ有効です。また効果は保護されたセクションの末尾に移動します。実行は例外ハンドラーの後の最初のステートメントで実行が続行されます。
goto のステートメントは保護されたセクションの外部にジャンプする留めるスタック アンワインドが発生しないため try-finally のステートメントのようにパフォーマンスが低下します。ただし保護されたセクションが大きく複雑またはプログラミングを押した場合はほとんどないため goto のステートメントではなく __leave のキーワードを使用することをお勧めします。
構造化例外処理の組み込み関数
構造化例外処理では とを除く ステートメントで使用できる 2 種類の組み込み関数が用意されています : GetExceptionCode と GetExceptionInformation。
GetExceptionCode は例外のコード (32 ビット整数) を返します。
組み込み関数 GetExceptionInformation は例外に関する追加情報が格納された構造体へのポインターを返します。このポインターを使用してハードウェア例外の場合に使用していたマシンの状態にアクセスできます。構造は、次のとおりです。
struct _EXCEPTION_POINTERS {
EXCEPTION_RECORD *ExceptionRecord,
CONTEXT *ContextRecord }
ポインター型の EXCEPTION_RECORD __ と コンテキスト はインクルード ファイル EXCPT.H. で定義されます。
例外ハンドラー内の GetExceptionCode を使用できます。ただし例外フィルター式内でのみ GetExceptionInformation を使用できます。これが指している情報はスタックにコントロールが例外ハンドラーに渡される場合でも使用できます。
組み込み関数 AbnormalTermination は終了ハンドラー内で使用できます。これは try-finally のステートメントの本体は順番に終了した場合は 0 を返します。それ以外の場合は手順 1. を返します。
EXCPT.H はこれらの組み込みは別の名前を定義します :
GetExceptionCode は _exception_code と同じです。
GetExceptionInformation は _exception_info と同じです。
AbnormalTermination は _abnormal_termination と同じです。
使用例
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION) {
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else {
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try{
puts("in try");
__try{
puts("in try");
*p = 13; // causes an access violation exception;
}__finally{
puts("in finally. termination: ");
puts(AbnormalTermination() ? " \tabnormal" : "\tnormal");
}
}__except(filter(GetExceptionCode(), GetExceptionInformation())){
puts("in except");
}
puts("world");
}
出力
hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
abnormal
in except
world
終了 Microsoft 固有の仕様→