Thinking Different





SEH (Structured Exception Handler)?

구조적 예외처리라고 한다. 예외될 내용들을 한번에 모아서 처리하는 것을 말한다.

이론적으로 보면 굉장히 멋지고 한번에 처리 할 수 있어서 가독성도 좋아보일듯 하고, 매력적으로 보인다

보통 자바에서 많이 쓰이는 try - catch 구문이 바로 그것이다.. 


간단한 예제를 보도록 하자

먼저 기본적인 if else를 통한 예외처리 부분이다. 아래와 같이 각각 if문을 통해서 예외상황이 발생할 때마다 그때그때 처리를 해주어야 하는것을 볼 수 있다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    FILE* fp = fopen("c:\\test.txt", "r");
    if(fp == NULL)
    {
        // 예외 처리1
    }
 
    char* buf = new char[256];
    if(buf == NULL)
    {
        // 예외 처리2
    }
 
    // do something...
 
    if(fp != NULL)
        fclose(fp);
 
    if(buf != NULL)
        delete buf;

 


두번째로 try - catch 구문을 적용한 모습이다. 예외구문을 간단히 try에서 실행하고 catch로 예외코드를 throw 날려서 해당되는 에러 번호에 대해 처리하는 부분이 있고 마지막으로 finally 구문에서 할당된 내용들을 해제하는 코드로 이루어져 있다. 코드가 좀 길어진거 같긴 하지만 예제코드라서 양해바랍니다.
코드 가독성은 좀 증가(?) 한걸로 보여진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    FILE* fp        = NULL;
    char* buf    = NULL;
 
    try
    {
        fp = fopen("c:\\test.txt", "r");
        if(fp == NULL)
            throw 1;
 
        buf = new char[256];
        if(buf == NULL)
            throw 2;
    }
    catch(int error)
    {
        switch(error)
        {
        case 1:
            cout << "File Open Error!" << endl;
            break;
 
        case 2:
            cout << "Not enough memory!" << endl;
            break;
        }
    }
    finally
    {
        if(fp != NULL)
            fclose(fp);
 
        if(buf != NULL)
            delete buf;
    }
 


위에서 간단히 코드의 비교문을 보면서 이렇게 사용하는구나 생각할 수 있습니다...  

자 이제 본론으로 들어가서 try-catch에 대한 불편한 진실에 대해서 말씀을 드릴까 합니다. 겉으로 보기에 깔끔하고 가독성을 증가시켜주고 중복 코드를 줄임으로써 개발자에게 좋은 방법이 될수 있겠지만,

More Effective C++ 책에 의하면 try-catch 블록을 쓰기만 해도 런타임시 실행 속도가 5 ~ 10 % 늘어난다고 합니다. 예외 처리 비용이 너무 많이 듭니다. 

또한, 실제 예외가 발생(throw)하여 함수로 복귀하는데에는 1000배 만큼 느려진다고 하는군요.  try-catch 문에서 사용되는 스택되감기(Stack Unwinding) 라는 녀석때문에 성능이 저하되는 부분이 상당하다고 합니다.

필자는 자바를 개인적으로 별로 좋아하지 않는데, virtual machine(가상머신) 상에서 돌아가는 것도 있지만, try-catch 구문에 의한 처리 및 기타 코딩상의 추가 작업들 등 코드 비용들 등이 많아서 프로그램이 무겁게 느껴진다는게 개인적인 생각입니다.

try-catch 문의 단점

1. 프로그램의 성능이 눈에 띄게 느려진다(스택 되감기 등..)
2. try-catch를 쓰게 되면서 프로그램 용량이 커지게된다.(try-catch 사용에 따른 부가 소스 길이 증가)
3. 전통적인 if-else 문을 모조리 바꿀 수 없다( 못바꾸는 예가 있다 )
4. 동적할당한 메모리가 해제안될 수 있다.( throw 때문에 )
5. 템플릿에는 쓸 수 없다.( 예외 객체에 어디에 받아야 하는지 모르기때문!! ) 



마지막으로 내가 생각하는 예외처리 try-catch 에 대한 지향은 다음과 같습니다.



"try-catch...  꼭 필요하지 않으면 쓰지말자!"



 
Visual Studio 예외처리 옵션 부분
프로젝트 속성 - C/C++ - 코드생성 - c++ 예외 처리 가능 (EHa -> 아니오) 로 지정