기록공간

예외 처리 본문

C++

예외 처리

입코딩 2020. 4. 21. 22:51
반응형

C++은 유연한 언어이지만 안전한 언어는 아니다. 엉뚱한 메모리 참조나 비정상적인 연산(0으로 나누기)을 시도해도 컴파일러가 걸러주지 않는다. C++의 exception은 코드의 안정성을 한 단계 높이기 위해 언어 차원에서 제공하는 기능이다.

 

exception에는 몇 가지 새로운 용어가 도입되었다. 특정 코드가 예외적인 상황을 인지하면 exception을 던진다(throw). 그리고 다른 코드가 던져진 exception을 받아서(catch) 필요한 처리를 한다. 다음은 0 나누기가 발생할 때 exception을 던지는 예제이다.

#include <stdexcept>

double divideNumbers(double numerator, double denominator)
{
    if(denominator == 0)
    {
        throw std::invalid_argument("Denominator cannot be 0.");
    }
    return numerator / denominator;
}

throw 구문에 이르면 리턴값도 없이 함수의 실행이 즉시 중단된다. 다음 예제와 같이 호출한 측에서 이 함수를 try / catch 블록으로 감쌌다면 던져진 exception을 받아서 처리하게 된다.

#include <iostream>
#include <exception>

int main()
{
    try
    {
        std::cout << divideNumbers(2.5, 0.5) << std::endl;
        std::cout << divideNumbers(2.3, 0) << std::endl;
        std::cout << divideNumbers(4.5, 2.5) << std::endl;
    }
    catch(const std::exception& exception)
    {
        std::cout << "Exception caught : " << exception.what() << std::endl;
    }
}

divideNumbers() 함수의 첫 번째 호출은 정상적인 결과를 리턴한다. 하지만 두 번째 호출은 분모의 파라미터가 0이기 때문에 리턴값 없이 exception이 발생하고 catch 블록에서 실행 흐름을 넘겨받아 에러 메시지를 출력한다. 두 번째 호출에서 exception이 발생하여 catch블록으로 점프했기 때문에 세 번째 호출은 실행되지 않는다. 실행 결과는 다음과 같다.

5
An exception was caught : Denominator cannot be 0.

exception은 사용하기에 따라 굉장히 난해해질수도 있다. exception을 제대로 이용하려면 exception을 throw할 때 스택 변수에 무슨 일이 일어나는지 정확히 이해하고 이를 바탕으로 catch 블록에서 작업을 적절히 구성해야 한다. Jave와 다르게 C++은 모든 exception에 대해 catch 구문을 강제하지 않는다. 호출 과정에서 catch 블록이 없다면 exception이 throw 될때 표준 라이브러리가 그 exception을 받게 되고 프로그램이 종료된다.  

반응형

'C++' 카테고리의 다른 글

round 반올림 메서드 (C++ 11)  (0) 2020.06.25
std::getline()을 이용한 string 표준입력  (0) 2020.06.25
스마트 포인터 - 간략하게  (0) 2020.04.07
decltype 키워드  (0) 2020.04.03
자동 함수 리턴 타입 (C++14)  (0) 2020.04.03
Comments