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를 사용하면 오류 정보를 표시하고 애플리케이션의 내부 상태를 트래핑하여 문제를 진단할 수 있습니다. 재현하기 쉽지 않은 일시적인 문제에 특히 유용합니다.

참고 항목

구조적 예외 처리는 Win32에서 C 및 C++ 소스 파일에 대해 작동하지만 그러나 C++용으로 특별히 설계된 것은 아닙니다. C++ 예외 처리를 사용하여 코드의 이식성이 향상되는지 확인할 수 있습니다. 또한 C++ 예외 처리는 모든 형식의 예외를 처리할 수 있다는 점에서 보다 유연합니다. C++ 프로그램의 경우 네이티브 C++ 예외 처리( try, catch 및 throw 문)를 사용하는 것이 좋습니다.

절 뒤의 __try 복합 문은 본문 또는 보호 구역입니다. 식 __except 은 필터 식이라고도합니다. 해당 값은 예외가 처리되는 방법을 결정합니다. __except 절 뒤에 오는 복합 문은 예외 처리기입니다. 처리기는 본문 섹션을 실행하는 동안 예외가 발생하는 경우 수행할 작업을 지정합니다. 다음과 같이 실행됩니다.

  1. 보호된 섹션이 실행됩니다.

  2. 보호된 섹션을 실행하는 동안 예외가 발생하지 않는 경우 __except 절 다음의 문에서 실행이 계속됩니다.

  3. 보호된 섹션을 실행하는 동안 또는 보호된 섹션이 호출하는 루틴에서 예외가 발생하면 식이 __except 평가됩니다. 세 가지 값을 사용할 수 있습니다.

    • EXCEPTION_CONTINUE_EXECUTION (-1) 예외가 해제됩니다. 예외가 발생한 지점에서 계속 실행합니다.

    • EXCEPTION_CONTINUE_SEARCH (0) 예외가 인식되지 않습니다. try-except 문을 포함하는 처리기를 먼저 검색한 후, 그 다음으로 우선 순위가 높은 처리기를 검색하는 순으로 처리기 스택을 계속 검색합니다.

    • EXCEPTION_EXECUTE_HANDLER (1) 예외가 인식됩니다. 복합 문을 실행하여 예외 처리기로 제어를 __except 전송한 다음 블록 이후에 실행을 계속합니다 __except .

식은 __except C 식으로 평가됩니다. 단일 값, 조건식 연산자 또는 쉼표 연산자로 제한됩니다. 더 광범위한 처리가 필요한 경우 식은 위에 나열된 세 값 중 하나를 반환하는 루틴을 호출할 수 있습니다.

각 애플리케이션에는 자체 예외 처리기를 사용할 수 있습니다.

문으로 __try 이동하는 것은 유효하지 않지만 한 문에서 뛰어내리면 유효합니다. 문을 실행하는 try-except 동안 프로세스가 종료되면 예외 처리기가 호출되지 않습니다.

이전 버전과의 호환성을 위해 컴파일러 옵션 /Za(언어 확장 사용 안 함)를 지정하지 않는 한 _try, _except__leave_leave 동의어__try__except입니다.

__leave 키워드

__leave 키워드(keyword) 문의 보호된 섹션 try-except 내에서만 유효하며, 그 효과는 보호된 섹션의 끝으로 이동하는 것입니다. 실행은 예외 처리기 뒤에 나오는 첫 번째 문에서 계속 됩니다.

goto 또한 문이 보호된 섹션에서 벗어날 수 있으며 try-finally 문에서처럼 성능이 저하되지 않습니다. 스택 해제가 발생하지 않기 때문입니다. 그러나 문 대신 goto 키워드(keyword) 사용하는 __leave 것이 좋습니다. 보호된 섹션이 크거나 복잡한 경우 프로그래밍 실수를 할 가능성이 적기 때문입니다.

구조적 예외 처리 내장 함수

구조적 예외 처리는 GetExceptionCodeGetExceptionInformation과 함께 try-except 사용할 수 있는 두 가지 내장 함수를 제공합니다.

GetExceptionCode 는 예외의 코드(32비트 정수)를 반환합니다.

내장 함수 GetExceptionInformation 는 예외에 대한 추가 정보를 포함하는 EXCEPTION_POINTERS 구조체에 대한 포인터를 반환합니다. 이 포인터를 통하여, 하드웨어 예외 발생 시의 컴퓨터 상태에 액세스할 수 있습니다. 구조는 다음과 같습니다.

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

포인터 형식 PEXCEPTION_RECORD 이며 포함 파일 winnt.h _EXCEPTION_RECORD>_CONTEXT 에 정의되며 포함 파일 <<excpt.h에 정의됩니다.PCONTEXT>

예외 처리기 내에서 사용할 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

참고 항목

예외 처리기 작성
Structured Exception Handling (C/C++)
키워드