예외 전파

C++ 예외 전파 조건

throw가 catch로 이동한다는 한 줄 설명은 예외 흐름의 위험을 숨긴다. 예외 객체가 만들어지고, 스택이 풀리며 RAII 소멸자가 실행되고, 가장 가까운 matching catch가 선택되며, noexcept나 소멸자 예외에서는 terminate로 이어질 수 있다.

01

예외 객체 생성

throw 표현식으로 예외 객체가 만들어지고 정적 타입과 동적 타입이 catch 선택에 영향을 준다.

값으로 던지고 참조로 받는 패턴을 자주 쓴다
02

스택 풀기

호출 스택을 거슬러 올라가며 지역 객체의 소멸자가 실행된다.

RAII 소멸자가 여기서 작동한다
03

catch 매칭

위에서 아래 순서로 타입이 맞는 catch를 찾으므로 파생 타입을 먼저 둔다.

catch(...)는 마지막에 둔다
04

noexcept 확인

noexcept 함수 밖으로 예외가 나가면 terminate가 호출된다.

컨테이너 이동 최적화에도 noexcept가 영향을 준다
05

소멸자 예외 차단

스택 풀기 중 소멸자에서 또 예외가 나오면 terminate 위험이 커진다.

소멸자는 예외를 밖으로 내보내지 않는다
throw by value
예외 객체 생성 지역 객체 포인터를 던지지 않고 값으로 예외 객체를 만든다.
catch는 const reference가 일반적이다
catch order
구체 타입 우선 파생 예외를 먼저, base exception을 나중에 둔다.
순서가 틀리면 뒤 catch가 죽는다
RAII
소멸자 보장 스택 풀기 중 소멸자가 자원을 닫는다.
manual cleanup보다 안전하다
terminate
복구 불가 종료 noexcept 위반, 소멸자 중 이중 예외, uncaught 예외에서 발생할 수 있다.
경계에서 catch한다

예외 확인

catch 순서 파생 예외 catch가 base catch보다 앞에 있는지 확인한다.
noexcept 경계 noexcept 함수에서 예외가 빠져나가지 않는지 본다.
RAII 정리 예외 발생 시 파일, 락, 메모리가 소멸자로 정리되는지 확인한다.