예외처리의 필요성 --------------------------------------------------------------------------------------------------

프로그래밍에서 예외처리의 중요성이란 두말할 필요가 없다.

단순히 하나의 함수만 처리한다고 하더라도 예외처리란 각 작업에 맞는 모든 상황에 대처하기 위한 처리가 필요하다.

예외처리는 철저하게 되어야 하고 게임출시전에 최대한 모든 코드가 예외를 통해서 검증 되어야 한다.


예외와 에러의 차이점 -----------------------------------------------------------------------------------------------


일단 그런거 없고 다 내가 잘못한 거라고 생각하자. 오류가 날 상황이라도 예외처리를 잘 해놓는다면 그 위치가 어디인지 정확하게 알수가 있으며 예외와 오류는 결국 개발하는 사람들의 몫이라고 본다. 프로그래머가 예측가능한 모든 오류는 예외라고 할 수 있겠다.


하드웨어 예외, 소프트웨어 예외 --------------------------------------------------------------------------------------

프로그램 실행 시 예측 가능한 모든 문제점을 예외로 인식하기로 하였다.

하나는 하드웨어예외이고 다른 하나는 소프트웨어 예외이다.

1. 하드웨어 예외 -> 하드웨어에서 인식하고 알려주는 예외를 의미한다. 문제는 응용프로그램이 냈지만 예외를 캐치하는 주체는 하드웨어에서 알려준다.

2. 소프트웨어 예외 -> 소프트웨어에서 인식하고 알려주는 예외로 운영체제와 비쥬얼스튜디오 심지어는 디버깅 프로그램에서 알려주는 예외를 포함한다.


예외처리 매커니즘의 종류 -------------------------------------------------------------------------------------------

구조적 예외처리 매커니즘은 크게 2가지로 나눌수가 있다.

1. 종료 핸들러 

2. 예외 핸들러  


종료 핸들러 -------------------------------------------------------------------------------------------------------

int a, b;


__try // 이안의 내용을 한줄이라도 실행한다면 

{

_tprintf( _T("input divide string [a/b]") ) 

_tscanf( _T("%d / %d", &a, &b) );


if(b == 0) 

return -1; -> 리턴보다도 __fianlly가 먼저 실행된다.

}

__fianlly //이 안의 내용을 실행하라.

{

_tprintf( _T("__finally block! \n") );

}


에러에 의해서 메모리 해제가 제대로 되지 않을때나. 릴리즈 해야할 오브젝트를 삭제하지 못하고 프로그램이 종료될만한 예외가 발생하는 상황에서 특히 잘 이용할수가 있다.


예외 핸들러 -------------------------------------------------------------------------------------------------------

__try        // 예외가 발생하면

__except  // 블록에서 상황을 처리하고 try구문은 무시한다.


int * p = NULL;


__try // 예외가 생기면 이녀석을 무시한다.

{

*p = 100;

_tprintf( _T("__value : %d \n"),  *p);

}

__except(EXCEPTION_EXECUTE_HANDLER) // 예외가 생기면 이 녀석을 처리한다.

{

_tprintf( _T("__finally \n") );

}


_tprintf( _T("result : %d \n") );


만약 __try문 내의 사용자지정 함수에서 예외가 발생해도 __try내부의 에러로 인식하게 되니 그에 따른 적절한 이용이 필요하다.


핸들러 중복 -------------------------------------------------------------------------------------------------------

__try

__try

__fianlly

__except(EXCEPTION_EXECUTE_HANDLER)

이런식으로 연속적으로 트라이를 겹쳐서 사용하는것이 가능하다.


예외 종류의 확인과 사용법 -------------------------------------------------------------------------------------------

GetExceptionCode()라는 함수가 존재하며 이 함수는 만약 예외 상황이 발생하면 어떠한 예외 상황이었는지 그 값을 DWORD형으로 알려준다,.

__try

{


}

__except(EXCEPTION_EXECUTE_HANDLER)

{

DWORD dwExcept = GetExceptionCode();


// dwExcept 변수는 이제부터 예외에 대한 키를 가진다.

}


__except( 예외 처리용 함수( GetExceptionCode() ) )

예외처리용 함수를 예외 핸들러에 대신 넣을 수도 있다.


소프트웨어 예외 -------------------------------------------------------------------------------------------

소프트웨어 예외란 사용자가 결정해야하는 예외를 의미한다,.

하드웨어 예외는 이미 결정되어 있기 때문에 어떤 수단을 사용한다고 하더라도 추가가 불가능하다.

그러나 소프트웨어 예외는 소프트웨어가 디자인될때 결정되기 때문에 얼마든지 추가가 가능하다.


예외를 추가시키는 함수


void WINAPI RaiseException(

  _In_  DWORD dwExceptionCode, -> 발생시킬 예외 형태

  _In_  DWORD dwExceptionFlags, -> 예외 발생이후의 실행방식 제한

  _In_  DWORD nNumberOfArguments, -> 추가 정보의 개수

  _In_  const ULONG_PTR *lpArguments -> 추가 정보를 전달한다.

);

이 함수에 대한 설정과 인자값은 많은 예문과 설명이 필요하므로 이곳에 따로 적지는 않는다.


assert ---------------------------------------------------------------------------------------------------

assert코드는 간단히 설명해 보자면 디버그모드에서는 실행되고

릴리즈 모드에서는 실행되지 않는 디버깅 코드를 의미한다.

즉 릴리즈(출시버전)에서는 이 디버깅모드는 사용되지 않는다는 것이다.


사용법도 간단하다.


#include <assert.h> -> 헤더를 참조하고

public static void MyMethod(Object object)

{


     Debug.Assert(object != null, "object 매개 변수가 null입니다."); // 조건식을 써넣고 거기에 띄워줄 메세지도 넣을 수 있다.


      /* 작업 수행 */

}


이에 대한 의견으로는 

if (!expr) /* error-handling code */

처럼 쓰는 것이 바람직하다는 거죠. 실행 중에 abort()를 하는 것은 사용자
입장에서는 욕나오는 일일 테니까요.
"assert를 쓰는 것은 연습에서는 중무장하다가 실전에서는 맨몸으로 나가는 
것과 같다"는 말을 들었는데 정말 맞는 말이라고 생각합니다.

assert는 디버깅용에만 써야 하고, 디버깅 코드만 기술해야 하고, 절대 일어나서는 안되는 알고리즘상의 버그를 찾는 곳에 사용한다면 문제없다고 생각합니다.

최종 릴리즈 시에는 제거되는 코드들이므로 assert 때문에 abort 가 호출되지는 않겠지만 앞의 조건을 만족한다면 디버깅은 편하고 릴리즈는 탄탄하면서 빠른 코드가 생길 것이라고 생각합니다.

어쩔 수 없이 일어날 수밖에 없는 사용자의 입력 에러나 데이터 에러는 assert 로 해서는 절대 안되고 정상적인 에러 처리 루틴으로 처리해야 하는 것이 당연하다고 생각합니다.


같은 의견이 있으니 참고하면 이용이 편할 것 같다.


Posted by JJOREG