Structured Exception Handling (C/C++)
SEH(구조적 예외 처리)는 하드웨어 오류와 같은 특정 예외 코드 상황을 정상적으로 처리하기 위해 C 및 C++에 대한 Microsoft 확장입니다. Windows 및 Microsoft C++는 SEH를 지원하지만 C++ 코드에서 ISO 표준 C++ 예외 처리를 사용하는 것이 좋습니다. 코드를 더 이식 가능하고 유연하게 만듭니다. 그러나 기존 코드 또는 특정 종류의 프로그램을 기본 위해 SEH를 사용해야 할 수 있습니다.
Microsoft 전용:
문법
try-except-statement
:
__try
compound-statement
__except
(
filter-expression
)
compound-statement
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
설명
SEH를 사용하면 실행이 예기치 않게 종료될 경우 메모리 블록 및 파일과 같은 리소스가 올바르게 해제되도록 할 수 있습니다. 문이나 반환 코드의 정교한 테스트에 의존 goto
하지 않는 간결한 구조화된 코드를 사용하여 특정 문제(예: 메모리 부족)를 처리할 수도 있습니다.
이 try-except
문서에서 참조하는 명령문 및 try-finally
문은 C 및 C++ 언어에 대한 Microsoft 확장입니다. 둘 다 애플리케이션이 그렇지 않을 경우 실행을 종료하는 이벤트 후에 프로그램을 제어할 수 있도록 하여 SEH를 지원합니다. SEH는 C++ 소스 파일에서 작동하지만 C++용으로 특별히 설계된 것은 아닙니다. 또는/EHsc
옵션을 사용하여 컴파일하는 C++ 프로그램에서 SEH를 사용하는 /EHa
경우 로컬 개체에 대한 소멸자가 호출되지만 다른 실행 동작은 예상과 다를 수 있습니다. 일러스트레이션은 이 문서의 뒷부분에 있는 예제를 참조하세요. 대부분의 경우 SEH 대신 ISO 표준 C++ 예외 처리를 사용하는 것이 좋습니다. C++ 예외 처리를 사용하면 코드 포팅 가능성이 향상되며 모든 형식의 예외를 처리할 수 있습니다.
SEH를 사용하는 C 코드가 있는 경우 C++ 예외 처리를 사용하는 C++ 코드와 혼합할 수 있습니다. 자세한 내용은 C++의 구조적 예외 처리를 참조 하세요.
SEH 메커니즘에는 다음 두 가지가 있습니다.
값에
filter-expression
따라 예외에 응답하거나 해제할 수 있는 예외 처리기 또는__except
블록입니다. 자세한 내용은 문을 참조하세요try-except
.예외가 종료를 발생시키는지 여부에 관계없이 항상 호출되는 종료 처리기 또는
__finally
블록입니다. 자세한 내용은 문을 참조하세요try-finally
.
이러한 두 종류의 처리기는 고유하지만 스택 해제라고 하는 프로세스를 통해 밀접하게 관련됩니다. 구조적 예외가 발생하면 Windows는 현재 활성 상태인 가장 최근에 설치된 예외 처리기를 찾습니다. 처리기는 다음 세 가지 작업 중 하나를 수행할 수 있습니다.
예외를 인식하지 못하고 컨트롤을 다른 처리기(
EXCEPTION_CONTINUE_SEARCH
)에 전달합니다.예외를 인식하지만 해제합니다(
EXCEPTION_CONTINUE_EXECUTION
).예외를 인식하고 처리합니다(
EXCEPTION_EXECUTE_HANDLER
).
예외가 발생할 때 실행 중이던 함수에 예외를 인식하는 예외 처리기가 없을 수 있습니다. 스택에서 훨씬 더 높은 함수에 있을 수 있습니다. 현재 실행 중인 함수 및 스택 프레임의 다른 모든 함수가 종료됩니다. 이 프로세스 중에 스택이 해제됩니다. 즉, 종료된 함수의 로컬 비정적 변수가 스택에서 지워집니다.
스택을 해제할 때 운영 체제는 각 함수에 대해 작성된 종료 처리기를 모두 호출합니다. 종료 처리기를 사용하면 비정상적인 종료로 인해 다시 열려 기본 리소스를 클린. 중요한 섹션을 입력한 경우 종료 처리기에서 종료할 수 있습니다. 프로그램이 종료되는 경우 임시 파일 닫기 및 제거와 같은 다른 하우스키핑 작업을 수행할 수 있습니다.
다음 단계
예시
앞에서 설명한 것처럼 C++ 프로그램에서 SEH를 사용하고 또는 /EHsc
옵션을 사용하여 /EHa
컴파일하는 경우 로컬 개체에 대한 소멸자가 호출됩니다. 그러나 C++ 예외를 사용하는 경우 실행 중 동작이 예상과 다를 수 있습니다. 이 예제에서는 이러한 동작 차이점을 보여 줍니다.
#include <stdio.h>
#include <Windows.h>
#include <exception>
class TestClass
{
public:
~TestClass()
{
printf("Destroying TestClass!\n");
}
};
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
printf("Throwing C++ exception\n");
throw std::exception("");
#else
printf("Triggering SEH exception\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\n");
}
return 0;
}
이 코드를 컴파일하는 데 사용 /EHsc
하지만 로컬 테스트 제어 매크로 CPPEX
가 정의 TestClass
되지 않은 경우 소멸자가 실행되지 않습니다. 출력은 다음과 같습니다.
Triggering SEH exception
Executing SEH __except block
코드를 CPPEX
컴파일하는 데 사용하고 /EHsc
C++ 예외가 throw TestClass
되도록 사용하여 /DCPPEX
정의되는 경우 소멸자가 실행되고 출력은 다음과 같이 표시됩니다.
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
코드를 TestClass
컴파일하는 데 사용하는 /EHa
경우 소멸자가 표준 C++ throw
식을 사용하거나 SEH를 사용하여 예외가 throw되었는지 여부를 실행합니다. 즉, 정의되었는지 여부 CPPEX
입니다. 출력은 다음과 같습니다.
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
자세한 내용은 (예외 처리 모델)을 참조 /EH
하세요.
END Microsoft 전용
참고 항목
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기