Share via


구조적 예외 처리 (C/C++)

비록 Windows 및 Visual C++가 구조적된 예외 처리 (SEH)를 지원 하지만, 이식 가능하고 유연한 코드를 만들기 위해 ISO 표준 C++ 예외 처리를 사용 하는 것이 좋습니다. 그럼에도 불구하고, 기존 코드 또는 특정 종류의 프로그램에서, 당신은 계속 해야 SEH를 사용 합니다.

문법

try-except-statement :

__try compound-statement

__except ( expression ) compound-statement

설명

SEH를 사용하여, 실행이 예기치 않게 종료되는 지 정확하게 메모리 블록, 파일 등의 리소스를 확인할 수 있습니다. 또한, goto 문 또는 반환 코드는 상세한 테스트에 의존하지 않는 간결한 구조화된 코드에 의해 특정한 문제들을 예를 들어, 메모리 부족 처리할 수 있습니다.

이 문서에서 참조 하는 Try-제외 및 try-finally 문은 C 언어에 대한 Microsoft 확장입니다. 그들은 그렇지 않으면 실행을 종료 하는 이벤트 후 프로그램의 제어를 얻기 위해 응용 프로그램을 사용하여 SEH를 지원 합니다. 비록 SEH가 C++ 소스 파일을 사용 하여 작동 하지만, C++에 대해 특별히 설계 되지 않았습니다. C++ 프로그램에서 SEH를 사용 하여 컴파일하는 경우 해당 /EH 옵션을 사용하면 — 특정 한정자와 함께ㅡ로컬 개체에 대한 소멸자는 호출 되지만 예상과 다른 실행 동작을 할 수 있습니다. (그림은, 이 글의 다음 예제 를 참조하십시오.) 대부분의 경우, SEH 대신 ISO-표준이고 Visual C++이 지원하는 C++ 예외 처리 를 사용하는 것을 권장합니다. C++ 예외 처리를 사용함으로써, 코드는 더 이식 가능 해지는 것을 확인할 수 있고, 모든 종류의 예외를 처리할 수 있습니다.

SEH를 사용 하는 C 모듈을 갖고 있으면, C++ 예외 처리를 사용한 C++ 예외 처리를 혼합할 수 있습니다. 자세한 내용은 예외 처리 차이점를 참조하십시오.

여기에는 두 개의 SEH 기술이 있습니다.

  • 예외에 응답하거나 예외를 무시할 수 있는 예외 처리기.

  • 예외가 코드 블록 내에서 종료를 발생하면 호출되는 종료 처리기

이 두 가지 종류의 조정기들은 분명하지만, 이들은 "스택해제"라고 알려진 과정을 통하여 밀접하게 관련이 있습니다. 예외가 발생하면 Windows는 현재 사용 중인 가장 최근에 설치된 예외 처리기를 찾습니다. 처리기는 다음 세 가지 중 하나를 수행할 수 있습니다.

  • 예외 인식에 실패하고 다른 처리기에 제어를 전달합니다.

  • 예외를 인식하지만 무시합니다.

  • 예외를 인식 하고 처리합니다.

예외를 인식하는 예외 처리기가 예외가 발생했을 때 실행 중이던 함수에 있지 않을 수 있습니다. 경우에 따라 스택에 훨씬 더 높은 함수가 있을 수 있습니다. 스택 프레임의 함수와 현재 실행 중인 함수도 종료됩니다. 이 프로세스 동안, 스택은 "해제"됩니다. 즉, 종료된 함수의 지역 변수는ㅡ그들이 static이 아닌 경우—스택에서 삭제됩니다.

운영 체제에서 스택을 해제할 때, 운영 체제는 각 함수에 대해 작성한 모든 종료 처리기를 호출합니다. 종료 처리기의 사용으로, 비정상적인 종료로 인해 열려 있는 리소스를 정리할 수 있는 기회를 제공합니다. 임계 영역을 입력했으면 종료 처리기에서 종료할 수 있습니다. 프로그램이 곧 종료될 경우, 닫기 및 임시 파일 제거와 같은 기타 관리 작업을 수행할 수 있습니다.

자세한 내용은 다음을 참조하십시오.

예제

앞서 설명한 것 처럼, C++ 프로그램에서 SEH를 사용한다면 로컬 개체의 소멸자는 호출되고 /EH 특정 한정자 옵션-예를 들어, /EHsc/EHa 를 사용함으로써 컴파일 합니다. 그러나, 만약 당신이 C++ 예외도 사용 하는 경우 동작은 예상 대로 실행 될 수 있습니다. 다음 예제에서는 이러한 동작의 차이를 보여 줍니다.

#include <stdio.h>
#include <Windows.h>
#include <exception>
 
class TestClass
{
public:
    ~TestClass()
    {
        printf("Destroying TestClass!\r\n");
    }
};
 
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
    printf("Throwing C++ exception\r\n");
    throw std::exception("");
#else
    printf("Triggering SEH exception\r\n");
    volatile int *pInt = 0x00000000;
    *pInt = 20;
#endif
}
 
__declspec(noinline) void TestExceptions()
{
    TestClass d;
    TestCPPEX();
}
 
int main()
{
    __try
    {
        TestExceptions();
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        printf("Executing SEH __except block\r\n");
    }
 
    return 0;
}

당신이 다음**/EHsc** 을 로컬 테스트 컨트롤이 아닌 이 코드를 컴파일하려면 CPPEX 가 정의되지 않아도, TestClass 소멸자의 실행은 없고 출력은 다음과 같습니다:

  

다음 /EHsc 를 코드를 컴파일하기 위해 사용하고 CPPEX 가 /DCPPEX (그래서 C++ 예외가 throw 됩니다)에 의해 정의된다면, TestClass 소멸자는 실행 하고, 출력은 다음과 같습니다:

  

/EHa 를 코드를 컴파일하는 데 사용한다면, TestClass 소멸자는 std::throw 을 사용함으로써 또는 예외를 발생시키는 SEH를 사용함으로써 던져진 예외와 관계없이 실행합니다 (CPPEX 가 정의 되건 안되건). 구문은 다음과 같습니다.

  

자세한 내용은 /EH(예외 처리 모델)을 참조하십시오.

참고 항목

참조

Visual C++에서 예외 처리

C++ 키워드

<exception>

개념

오류 및 예외 처리(최신 C++)

기타 리소스

구조체된 예외 처리 (Windows)