구조화된 예외
#include <stdio.h>
#include <Windows.h>
int main()
{
    int n = 0
    int s = 10 / 0;     // (컴파일러가 똑똑해 져서) 컴파일 에러 발생
}
int main()
{
    int n = 0
    int s = 10 / n;     // 런타임에 에러
}
런타임 에러가 발생하는 기전은
 기게어 코드에서 문제발생 -> CPU에 통보 -> Windows OS에 통보 -> IDE에 Exception을 전달
- C++에서 제공하는 예외가 아니라 Windows OS에서 제공하는 예외이다. 
__try{} __except{}를 이용해 예외를 잡아보자
 
int main()
{
    int n = 0
    // 아래와 같은 방식으로 Windows OS exception을 잡을 수 있다.
    __try
    {
        int s = 10 / n;
    }
    __except(1)
    {
        // 왜 죽었는지 확인방법
        printf("exception : %x\n", GetExceptionCode());
    }
}
__except()는 에 들어갈수 있는 매개변수는 세 가지이다.- EXCEPTION_EXECUTE_HANDER(1) : 일반적 예외
 - EXCEPTION_CONTINUE_SEARCH(2) : except를 받았지만 일단은 처리하지 않고 다름 try를 찾아라
 - EXCEPTION_CONTINUE_EXECUTION(-1) : 다시 try문을 시도해라
 
int n = 0
DWORD Filter(DWORD code)
{
    if(code == EXCEPTION_INT_DEVIDE_BY_ZERO)
    {
        printf("divide by zero");
        n = 5;
        return EXCEPTION_CONTINUE_EXECUTION;    // 재시도 해보시오
    }
    printf("other exception\n");
    return EXCEPTION_EXECUTE_HANDER;
}
int main()
{
    __try
    {
        int s = 10 / n;
    }
    __except(Filter(GetExceptionCode()))
    {
        // 참고로 GetExceptionCode()는 except내부에서만 호출이 가능하지 다른 함수에서 호출이 불가능
        printf("exception : %x\n", GetExceptionCode());
    }
}
어느 레지스터에 발생했는지 확인 방법
예외 발생시 스택에 예외 정보가 추가된다.
 GetExceptionInformation()을 통해 알 수있다.
 단, GetExceptionInformation()은 __exceptp(/*여기*/)에서만 호출이가능하다
 다른곳에서 호출 시 스택이 모두 지워진다.
#include <stdio.h>
#include <Windows.h>
DWORD Filter(EXCEPTION_POINTERS* ep)
{
    DWORD code = ep->ExceptionRecord->ExceptionCode;
    void* addr = ep->ExceptionRecord->ExceptionAddress;
    // ep->ContextRecord->Eip;
    return EXCEPTION_EXECUTE_HANDER;
}
int main()
{
    int n = 0;
    __try
    {
        int s = 10 / n;
    }
    __except(Filter(GetExceptionInformation())) 
    // GetExceptionInformation()는 __except의 매개변수로만 들어갈 수 있다는 점을 기억.
    {
        printf("exception : %x\n", GetExceptionCode());
    }
}
C++ 예외
class AAA
{
public:
    ~AAA() {}
};
int main()
{
    __try
    {
        // C++ 객체가 있으면 exception을 못잡음.
        // C++ 에서는 못쓴다는 말. 이후에 어떻게 사용될지 알려준다
        AAA aaa; // 디버그 에러
        char* p = 0;
        p = 0;  // Exception
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        printf("exceptin\n");
    }
}