try-except
明細書
try-except
ステートメントは、C と C++ 言語での構造化例外処理をサポートする Microsoft 固有の拡張機能です。
// . . .
__try {
// guarded code
}
__except ( /* filter expression */ ) {
// termination code
}
// . . .
構文
try-except-statement
:
__try
compound-statement
__except (
expression
)
compound-statement
解説
ステートメント try-except
は、C と C++ 言語の Microsoft 拡張機能です。 これにより、ターゲット アプリケーションは、プログラムの実行を通常終了するイベントが発生した場合に制御を取得できます。 このようなイベントは構造化例外と呼ばれるか、略して例外と呼ばれます。 これらの例外を処理する機構は構造化例外処理 (SEH) と呼ばれます。
関連情報については、「try-finally ステートメント」を参照してください。
例外は、ハードウェア例外またはソフトウェア例外です。 構造化例外処理は、アプリケーションがハードウェアまたはソフトウェアの例外から完全に回復できない場合でも役立ちます。 SEH を使用すると、エラー情報を表示し、問題の診断に役立つアプリケーションの内部状態をトラップすることができます。 特に、再現するのが難しい断続的な問題に対して役立ちます。
Note
構造化例外処理では、C と C++ のソース ファイルの両方で Win32 を使用します。 ただし、特に C++ 用にデザインされたものではありません。 C++ 例外処理を使用して、コードの移植性を高めることができます。 また、C++ 例外処理は、任意の型の例外を処理できるという点で、より柔軟です。 C++ プログラムの場合は、ネイティブの C++ 例外処理 (try、catch、throw ステートメント) を使用することをお勧めします。
__try
句の後の複合ステートメントは、本体または保護されたセクションです。 式 __except
はフィルター式とも呼ばれます。 例外を処理する方法は値によって決まります。 __except
句の後の複合ステートメントは、例外ハンドラーです。 ハンドラーによって、body セクションの実行中に例外が発生した場合に実行するアクションを指定します。 次のように実行されます。
保護されたセクションが実行されます。
保護されたセクションの実行中に例外が発生しなかった場合、実行は
__except
句の後のステートメントから続行されます。保護されたセクションの実行中、または保護されたセクションで呼び出された任意のルーチンで例外が発生した場合、
__except
式が評価されます。 指定可能な 3 つの値は次のとおりです。EXCEPTION_CONTINUE_EXECUTION
(-1) 例外は無視されました。 例外が発生した位置から実行を継続します。EXCEPTION_CONTINUE_SEARCH
(0) 例外は認識されません。 最初にtry-except
ステートメントを含むハンドラーを検索してから、次に優先順位が最も高いハンドラーについてスタックを検索し続けます。EXCEPTION_EXECUTE_HANDLER
(1) 例外は認識されました。__except
複合ステートメントの実行によって例外ハンドラーに制御を移動した後、__except
ブロックの次から実行を続行します。
__except
という式は、C 式と評価されます。 1 つの値、条件式演算子、またはコンマ演算子に制限されます。 より広範な処理が必要な場合、前に挙げた 3 つの値の 1 つを返すルーチンを式で呼び出すことができます。
各アプリケーションが独自の例外ハンドラーを持つ場合があります。
__try
ステートメント内に移動することはできませんが、外に移動することはできます。 例外ハンドラーは、try-except
ステートメントの実行中にプロセスが中止された場合は呼び出されません。
以前のバージョンとの互換性を確保するために、コンパイラ オプション /Za (言語拡張機能の無効化) が指定されていない限り、_try、_except、および _leave は __try
、__except
、および __leave
と同意語です。
__leave
キーワード
__leave
キーワードは、try-except
ステートメントの保護されたセクション内でのみ有効であり、その効果は保護されたセクションの末尾に移動することです。 実行は、例外ハンドラーの後の最初のステートメントから続行されます。
goto
ステートメントでも、保護されたセクションの外部に移動でき、try-finally ステートメントのようにパフォーマンスが低下しません。 これは、スタック アンワインドが発生しないためです。 ただし、goto
ステートメントではなく __leave
キーワードを使用することをお勧めします。 その理由は、保護されたセクションが大きい場合や複雑な場合にプログラミング ミスを行う可能性が低いためです。
構造化例外処理の組み込み関数
構造化例外処理には、try-except
ステートメントで使用できる 2 つの組み込み関数、GetExceptionCode および GetExceptionInformation が用意されています。
GetExceptionCode
は、例外のコード (32 ビット整数) を返します。
組み込み関数 GetExceptionInformation
は、例外に関する追加情報を含む EXCEPTION_POINTERS 構造体へのポインターを返します。 このポインターを使用して、ハードウェア例外のときに存在していたコンピューターの状態にアクセスできます。 構造は次のとおりです。
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
ポインター型 PEXCEPTION_RECORD
と PCONTEXT
は、インクルード ファイル <winnt.h> で定義され、_EXCEPTION_RECORD
および _CONTEXT
はインクルード ファイル <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
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示