'예외'에 해당되는 글 1건

  1. 2004.02.13 던지고 받기
dev.log2004. 2. 13. 02:37
대부분의 C++ 프로그래머들은 예외처리를 잘 쓰지 않는 경향이 있는 것 같다. 그 이유로는 첫째, 그들의 대부분이 C로 코딩을 하다가 C++로 migration한 사람이 대부분이고, 또 둘째로는 C++의 디자인이 자바처럼 예외처리를 장려하지는 않는다는 데 있는 듯 하다.

그래서 예외상황을 처리하기 위해서 대부분의 C++프로그래머들은 전통적인 '리턴값 체크'를 통해 에러를 감지하고 처리한다.

ifstream infile( "some_file_name" );
// .....
if ( infile.fail() )
{
   
// exception handling
    return;
}

대개는 위와 같은 형식이다. 그러나 위와 같은 에러처리를 하다보면 다음과 같은 코드가 컴파일되는 것을 사전에 방지할 도리가 없음을 알게 된다.
ifstream infile( "some_file_name" );
// .....
if ( infile.fail() )
{
    // exception handling..
    infile >> some_string;  // (1)
    // additional exception handling...
    return;
}

(1) 의 코드는 컴파일되는데 아무런 장애가 없다. 정상적으로 만들어진 객체에 정상적으로 선언된 메소드를 정상적으로 호출하는 코드이므로 컴파일러는 아무런 메시지도 내지 않고 컴파일해주게 된다. 그러나 문제는, (1)을 수행하는 시점에서 infile객체는 이미 에러를 내버린 개체라는 점이다. 에러를 처리하면서 에러를 낸 개체를 계속 사용하는 것은 위험한 일이다. 야구공이 실밥이 튿어졌다는 걸 발견하고 그걸 고치려는데 그걸 계속 던지고 놀아야 하겠는가?

C++예외처리의 장점은, try블럭에서 선언된 로컬 개체는 모두 try블럭 안에서만 로컬 스코프를 가진다는 점이다. 위의 코드를 예외처리를 사용하여 try-catch 블럭으로 바꾸면 대충 다음과 같은 꼴을 가질 것이다.

try
{
    ifstream infile( "some_file_name" );
    // .....
    if ( infile.fail() )
        throw ifstream_exception;
}
catch ( ifstream_exception e )
{
    // exception handling..
    infile >> some_string;  // (1)
    // additional exception handling...
    return;
}



위와 다른 점은, (1)의 코드를 컴파일할때 이번에는 컴파일러가 에러메시지를 뱉는다는 점이다. infile객체가 try블럭에서 로컬 스코프를 가지므로 예외가 trow된 순간 infile객체의 수명은 종료되고 catch블럭에서 infile개체에 대한 참조는 컴파일 에러를 내게 된다. 위의 if구문을 통한 에러처리보다 확실히 안전한 방법이라고 할 수 있다.
컴파일러가 한번 점검해 줌으로써 확실히 작동안하는 경우를 배제할 수 있는 방법이 마련된 것이다. 되도록이면 컴파일러에게 많은 일을 시키자.

Posted by uhm