try-except ステートメントtry-except Statement

Microsoft 固有の仕様Microsoft Specific

try-except ステートメントは C に対する Microsoft 拡張機能であり、構造化例外処理の C++ 言語をサポートします。The try-except statement is a Microsoft extension to the C and C++ languages that supports structured exception handling.

構文Syntax

__try__try
{{
    保護されたコード    // guarded code
}}
__except ( expression )__except ( expression )
{{
    例外ハンドラーのコード    // exception handler code
}}

RemarksRemarks

try-except ステートメントは C に対する Microsoft 拡張機能であり、C++ 言語を取得する対象アプリケーションをできるようにするプログラムの実行を正常に終了するイベントが発生したときを制御します。The try-except statement is a Microsoft extension to the C and C++ languages that enables target applications to gain control when events that normally terminate program execution occur. このようなイベントが呼び出されます例外、例外を処理するメカニズムを呼び出すと例外処理を構造化(SEH)。Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling (SEH).

関連情報については、try-finally ステートメントを参照してください。For related information, see the try-finally statement.

例外は、ハードウェア例外またはソフトウェア例外です。Exceptions can be either hardware-based or software-based. アプリケーションがハードウェア例外またはソフトウェア例外から完全に回復できない場合でも、構造化例外処理はエラー情報を表示し、問題の診断に役立つアプリケーションの内部状態をトラップすることができます。Even when applications cannot completely recover from hardware or software exceptions, structured exception handling makes it possible to display error information and trap the internal state of the application to help diagnose the problem. これは、簡単に再現できない断続的な問題の場合に特に便利です。This is especially useful for intermittent problems that cannot be reproduced easily.

注意

構造化例外処理では、C と C++ のソース ファイルの両方で Win32 を使用します。Structured exception handling works with Win32 for both C and C++ source files. ただし、特に C++ 用にデザインされたものではありません。However, it is not specifically designed for C++. C++ 例外処理を使用して、コードの移植性を高めることができます。You can ensure that your code is more portable by using C++ exception handling. また、C++ 例外処理は、任意の型の例外を処理できるという点で、より柔軟です。Also, C++ exception handling is more flexible, in that it can handle exceptions of any type. C++ プログラムは、お勧め、C++ 例外処理機構を使用すること (try、catch、および throwステートメント)。For C++ programs, it is recommended that you use the C++ exception-handling mechanism (try, catch, and throw statements).

後の複合ステートメント、 __try句は、本体または保護されたセクションです。The compound statement after the __try clause is the body or guarded section. 後の複合ステートメント、 __except句は、例外ハンドラー。The compound statement after the __except clause is the exception handler. ハンドラーは、保護されたセクションの本体の実行中に例外が発生した場合に行われる一連の操作を指定します。The handler specifies a set of actions to be taken if an exception is raised during execution of the body of the guarded section. 次のように実行されます。Execution proceeds as follows:

  1. 保護されたセクションが実行されます。The guarded section is executed.

  2. 実行は、ステートメントの後で続行、保護されたセクションの実行中に例外が発生しない場合、 __except句。If no exception occurs during execution of the guarded section, execution continues at the statement after the __except clause.

  3. 保護されたセクションの実行中に例外が発生したか、保護されたセクションを呼び出す任意のルーチンで、 __except (と呼ばれる、フィルター式)評価し、値が例外の処理方法を決定します。If an exception occurs during execution of the guarded section or in any routine the guarded section calls, the __except expression (called the filter expression) is evaluated and the value determines how the exception is handled. 指定できる値は 3 つあります。There are three possible values:

    • EXCEPTION_CONTINUE_EXECUTION (-1) の例外が閉じられます。EXCEPTION_CONTINUE_EXECUTION (-1) Exception is dismissed. 例外が発生した位置から実行を継続します。Continue execution at the point where the exception occurred.

    • EXCEPTION_CONTINUE_SEARCH (0) の例外が認識されていません。EXCEPTION_CONTINUE_SEARCH (0) Exception is not recognized. 最初に try-except ステートメントを含むハンドラーを検索してから、次に優先順位が最も高いハンドラーについてスタックを検索し続けます。Continue to search up the stack for a handler, first for containing try-except statements, then for handlers with the next highest precedence.

    • EXCEPTION_EXECUTE_HANDLER (1) の例外が認識されました。EXCEPTION_EXECUTE_HANDLER (1) Exception is recognized. 実行によって例外ハンドラーに制御を移動、 __except複合ステートメントの後の実行を続行し、 __exceptブロックします。Transfer control to the exception handler by executing the __except compound statement, then continue execution after the __except block.

__except式は C の式として評価される、単一の値を条件式演算子、またはコンマ演算子に制限されます。Because the __except expression is evaluated as a C expression, it is limited to a single value, the conditional-expression operator, or the comma operator. より広範な処理が必要な場合、前に挙げた 3 つの値の 1 つを返すルーチンを式で呼び出すことができます。If more extensive processing is required, the expression can call a routine that returns one of the three values listed above.

各アプリケーションが独自の例外ハンドラーを持つ場合があります。Each application can have its own exception handler.

移動することはできません、 __tryステートメントを 1 つからのジャンプは無効です。It is not valid to jump into a __try statement, but valid to jump out of one. 実行中のプロセスが終了した場合、例外ハンドラーは呼び出されませんが、try-exceptステートメント。The exception handler is not called if a process is terminated in the middle of executing a try-except statement.

以前のバージョンとの互換性のため _try_except、および _leaveのシノニムで __try__except__leaveしない限り、コンパイラ オプション/Za(言語拡張機能を無効にする)を指定します。For compatibility with previous versions, _try, _except, and _leave are synonyms for __try, __except, and __leave unless compiler option /Za (Disable language extensions) is specified.

__leave キーワードThe __leave Keyword

__Leaveキーワードの保護されたセクション内でのみ有効ですが、try-exceptステートメントとその効果は、保護されたセクションの末尾に移動します。The __leave keyword is valid only within the guarded section of a try-except statement, and its effect is to jump to the end of the guarded section. 実行は、例外ハンドラーの後の最初のステートメントから続行されます。Execution continues at the first statement after the exception handler.

gotoステートメントは、保護されたセクションからも進んでし、同様に、パフォーマンスは低下しません、 try-finallyステートメント スタック アンワインドが発生しないためです。A goto statement can also jump out of the guarded section, and it does not degrade performance as it does in a try-finally statement because stack unwinding does not occur. 使用すること勧めただし、 __leaveキーワードではなくgotoステートメントは、保護されたセクションが大規模または複雑な場合は、プログラミングの間違いを犯すことが少なくするためです。However, we recommend that you use the __leave keyword rather than a goto statement because you are less likely to make a programming mistake if the guarded section is large or complex.

構造化例外処理の組み込み関数Structured Exception Handling Intrinsic Functions

構造化例外処理で使用できるは 2 つの組み込み関数を提供する、try-exceptステートメント:GetExceptionCodeGetExceptionInformationします。Structured exception handling provides two intrinsic functions that are available to use with the try-except statement: GetExceptionCode and GetExceptionInformation.

GetExceptionCode 例外のコード (32 ビット整数) を返します。GetExceptionCode returns the code (a 32-bit integer) of the exception.

組み込み関数GetExceptionInformation例外に関する追加情報を含む構造体へのポインターを返します。The intrinsic function GetExceptionInformation returns a pointer to a structure containing additional information about the exception. このポインターを使用して、ハードウェア例外のときに存在していたコンピューターの状態にアクセスできます。Through this pointer, you can access the machine state that existed at the time of a hardware exception. 構造は、次のとおりです。The structure is as follows:

typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

ポインター型PEXCEPTION_RECORDPCONTEXTインクルード ファイルで定義されて<winnt.h >、および_EXCEPTION_RECORD_CONTEXTインクルード ファイルで定義されて<excpt.h >The pointer types PEXCEPTION_RECORD and PCONTEXT are defined in the include file <winnt.h>, and _EXCEPTION_RECORD and _CONTEXT are defined in the include file <excpt.h>

使用することができますGetExceptionCode例外ハンドラー内で。You can use GetExceptionCode within the exception handler. ただし、使用することができますGetExceptionInformation例外フィルター式内でのみです。However, you can use GetExceptionInformation only within the exception filter expression. これが示す情報は、一般的にスタックにあり、制御が例外ハンドラーに移されると使用できなくなります。The information it points to is generally on the stack and is no longer available when control is transferred to the exception handler.

組み込み関数AbnormalTerminationは終了ハンドラー内で使用できます。The intrinsic function AbnormalTermination is available within a termination handler. 場合は、0 を返しますの本文、 try-finallyステートメントが順次終了します。It returns 0 if the body of the try-finally statement terminates sequentially. その他の場合は、1 を返します。In all other cases, it returns 1.

excpt.h では、これらの組み込みの代替名を定義します。excpt.h defines some alternate names for these intrinsics:

GetExceptionCode 等価します。 _exception_codeGetExceptionCode is equivalent to _exception_code

GetExceptionInformation 等価します。 _exception_infoGetExceptionInformation is equivalent to _exception_info

AbnormalTermination 等価します。 _abnormal_terminationAbnormalTermination is equivalent to _abnormal_termination

Example

// 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");
}

出力Output

hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
        abnormal
in except
world

Microsoft 固有の仕様はここまでEND Microsoft Specific

関連項目See also

例外ハンドラーの記述Writing an Exception Handler
構造化例外処理 (C/C++)Structured Exception Handling (C/C++)
キーワードKeywords