다음을 통해 공유


/EH (예외 처리 모델)

컴파일러에서 생성된 예외 처리 모델 지원을 지정합니다. 인수는 구조적 및 표준 C++ 예외에 구문을 적용 catch(...) 할지 여부, "C" 코드가 예외로 throw 간주되는지 여부 extern 및 특정 noexcept 검사를 최적화할지 여부를 지정합니다.

구문

/EHa[-]
/EHs[-]
/EHc[-]
/EHr[-]

인수

a
표준 C++ 스택 해제를 사용하도록 설정합니다. 구문을 사용할 catch(...) 때 구조적(비동기) 및 표준 C++(동기) 예외를 모두 catch합니다. /EHa는 인수와 /EHc 인수를 모두 /EHs 재정의합니다.

s
표준 C++ 스택 해제를 사용하도록 설정합니다. 구문을 사용하는 catch(...) 경우 표준 C++ 예외만 catch합니다. 지정하지 않는 한 /EHc 컴파일러는 "C"extern 선언된 함수가 C++ 예외일 수 있다고 throw 가정합니다.

c
컴파일러는 "/EHsC"extern 선언된 함수가 C++ 예외가 없다고 throw 가정합니다. (즉, /EHca 동일한/EHa)과 함께 /EHa 사용할 때는 아무런 효과가 없습니다. /EHc 은 지정되지 않은 경우 /EHs /EHa 무시됩니다.

r
모든 noexcept 함수에 대해 항상 런타임 종료 검사를 생성하도록 컴파일러에 지시합니다. 기본적으로 noexcept 에 대한 런타임 검사는 컴파일러에서 함수가 throw되지 않는 함수만 호출하는 것을 확인하는 경우 최적화할 수 있습니다. 이 옵션은 일부 추가 코드의 비용으로 엄격한 C++ 규격을 제공합니다. /EHr 은 지정되지 않은 경우 /EHs /EHa 무시됩니다.

-
이전 옵션 인수를 지웁니다. 예를 들어 , /EHsc-/EHs /EHc-해석되며 ./EHs

/EH 인수는 순서에 관계없이 별도로 지정하거나 결합할 수 있습니다. 동일한 인수의 인스턴스가 둘 이상 지정된 경우 마지막 인스턴스는 이전 인스턴스를 재정의합니다. 예를 들어 , /EHr- /EHc /EHs 와 같/EHscr-으며 /EHscr- /EHr ./EHscr

설명

기본 예외 처리 동작

컴파일러는 항상 비동기 구조적 예외 처리(SEH)를 지원하는 코드를 생성합니다. 기본적으로 컴파일러는 네이티브 C++ catch(...) 절의 처리기를 지원합니다SEH(아니요 또는 옵션이 지정되어 있는 경우/EHsc/EHs/EHa). 그러나 C++ 예외만 부분적으로 지원하는 코드도 생성합니다. 기본 예외 해제 코드는 예외로 인해 범위를 벗어나는 블록 외부의 try 자동 C++ 개체를 삭제하지 않습니다. 리소스 누수 및 정의되지 않은 동작은 C++ 예외가 throw될 때 발생할 수 있습니다.

표준 C++ 예외 처리

스택 개체를 안전하게 해제하는 표준 C++ 예외 처리 모델에 대한 전체 컴파일러 지원( /EHsc 권장) /EHs또는 /EHa.

사용 /EHs 하거나 /EHsc사용하는 catch(...) 경우 절은 구조화된 예외를 비동기화하지 catch 않습니다. 액세스 위반 및 관리되는 System.Exception 예외는 catch되지 않습니다. 또한 코드가 비동기 예외를 처리하는 경우에도 비동기 예외가 발생하는 범위의 개체는 제거되지 않습니다. 이 동작은 구조적 예외를 처리되지 않은 상태로 두기 위한 인수입니다. 대신 이러한 예외를 치명적이라고 간주합니다.

사용 /EHs 하거나 /EHsc사용하는 경우 컴파일러는 문 또는 함수 호출에서만 예외가 throw 발생할 수 있다고 가정합니다. 이 가정을 사용하면 컴파일러가 해제할 수 없는 여러 개체의 수명을 추적하기 위한 코드를 제거할 수 있으므로 코드 크기를 크게 줄일 수 있습니다. 사용하는 /EHa경우 컴파일러가 블록을 적극적으로 최적화 try 하지 않으므로 실행 파일이 더 크고 느려질 수 있습니다. 또한 컴파일러에 C++ 예외를 수행할 수 throw 있는 코드가 표시되지 않더라도 로컬 개체를 자동으로 정리하는 예외 필터가 남습니다.

구조적 및 표준 C++ 예외 처리

/EHa 컴파일러 옵션을 사용하면 비동기 예외 및 C++ 예외 모두에 대해 안전한 스택 해제를 사용할 수 있습니다. 네이티브 C++ 절을 사용하여 표준 C++ 및 구조적 예외를 모두 처리할 수 catch(...) 있습니다. 지정하지 않고 구현 SEH 하려면 , __except__finally 구문을 사용할 __try수 있습니다./EHa 자세한 내용은 구조적 예외 처리를 참조 하세요.

Important

모든 예외를 /EHa 지정하고 사용하여 catch(...) 처리하려고 하면 위험할 수 있습니다. 대부분의 경우 비동기 예외는 복구할 수 없고 치명적인 것으로 간주해야 합니다. Catch하고 진행하면 프로세스가 손상되고 찾아 수정할 수 없는 버그를 일으킬 수 있습니다.

Windows 및 Visual C++가 지원 SEH되더라도 ISO 표준 C++ 예외 처리(/EHsc 또는 /EHs)를 사용하는 것이 좋습니다. 코드를 더욱 이식 가능하고 유연하게 만듭니다. 레거시 코드 또는 특정 종류의 프로그램에 사용해야 SEH 하는 경우가 여전히 있을 수 있습니다. 예를 들어 공용 언어 런타임(/clr)을 지원하기 위해 컴파일된 코드에서 필요합니다. 자세한 내용은 구조적 예외 처리를 참조 하세요.

컴파일된 개체 파일을 사용 /EHa 하거나 /EHsc 동일한 실행 모듈에서 컴파일된 /EHs 개체 파일에 연결하지 않는 것이 좋습니다. 모듈의 아무 곳이나 사용하여 /EHa 비동기 예외를 처리해야 하는 경우 모듈의 모든 코드를 컴파일하는 데 사용합니다 /EHa . 를 사용하여 컴파일된 코드와 동일한 모듈에서 구조적 예외 처리 구문을 사용할 수 있습니다 /EHs. 그러나 구문을 C++ trythrowcatch 동일한 함수와 혼합 SEH 할 수는 없습니다.

예외가 아닌 throw다른 항목에 의해 발생하는 경우 catch 사용합니다/EHa. 이 예제는 구조적 예외를 생성 및 catch합니다.

// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;

void fail()
{
    // generates SE and attempts to catch it using catch(...)
    try
    {
        int i = 0, j = 1;
        j /= i;   // This will throw a SE (divide by zero).
        printf("%d", j);
    }
    catch(...)
    {
        // catch block will only be executed under /EHa
        cout << "Caught an exception in catch(...)." << endl;
    }
}

int main()
{
    __try
    {
        fail();
    }

    // __except will only catch an exception here
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        // if the exception was not caught by the catch(...) inside fail()
        cout << "An exception was caught in __except." << endl;
    }
}

/clr에서 예외 처리

/clr 옵션은 (즉, /clr /EHa 중복됨)을 의미 /EHa 합니다. 컴파일러는 다음을 사용하는 /clr경우 /EHs /EHsc 오류를 생성합니다. 최적화는 이 동작에 영향을 주지 않습니다. 예외가 catch되면 컴파일러는 예외와 동일한 범위에 있는 모든 개체에 대해 클래스 소멸자를 호출합니다. 예외가 catch되지 않으면 해당 소멸자가 실행되지 않습니다.

아래/clr의 예외 처리 제한 사항에 대한 자세한 내용은 _set_se_translator 참조하세요.

런타임 예외 검사

/EHr 옵션은 특성이 noexcept 있는 모든 함수에서 런타임 종료 검사를 강제로 수행합니다. 기본적으로 런타임 검사는 컴파일러 백 엔드가 함수가 throw되지 않는 함수만 호출한다고 판단하는 경우 최적화될 수 있습니다. throw되지 않는 함수는 예외가 throw될 수 없음을 지정하는 특성을 갖는 모든 함수입니다. 여기에는 표시된 noexcept함수, throw()__declspec(nothrow)및 지정된 extern "C" 경우 /EHc 함수가 포함됩니다. throw되지 않는 함수에는 컴파일러에서 검사에 의해 throw되지 않는 것으로 확인한 모든 함수도 포함됩니다. 를 사용하여 /EHr-기본 동작을 명시적으로 설정할 수 있습니다.

throw되지 않는 특성은 함수에서 예외를 throw할 수 없다는 보장이 아닙니다. 함수의 noexcept 동작과 달리 MSVC 컴파일러는 함수를 사용하여 throw()__declspec(nothrow)선언된 함수 또는 extern "C" 정의되지 않은 동작으로 throw된 예외를 고려합니다. 이러한 세 가지 선언 특성을 사용하는 함수는 예외에 대한 런타임 종료 검사를 적용하지 않습니다. 이 옵션을 사용하면 /EHr 컴파일러가 함수를 이스케이프하는 처리되지 않은 예외에 대한 런타임 검사를 생성하도록 강제하여 이 정의되지 않은 동작을 식별할 수 있습니다 noexcept .

Visual Studio에서 또는 프로그래밍 방식으로 옵션 설정

Visual Studio 개발 환경에서 이 컴파일러 옵션을 설정하려면

  1. 프로젝트의 속성 페이지 대화 상자를 엽니다. 자세한 내용은 Visual Studio에서 C++ 컴파일러 및 빌드 속성 설정을 참조하세요.

  2. 구성 속성>C/C++>코드 생성을 선택합니다.

  3. C++ 예외 처리 가능 속성을 변경합니다.

    또는 C++ 예외 처리 가능아니요로 설정하고, 명령줄 속성 페이지에서, 추가 옵션 상자에 컴파일러 옵션을 추가합니다.

프로그래밍 방식으로 이 컴파일러 옵션을 설정하려면

참고 항목

MSVC 컴파일러 옵션
MSVC 컴파일러 명령줄 구문
오류 및 예외 처리
예외 사양(throw)
Structured Exception Handling (C/C++)