C++가 “We have try at home”라고 말한다

발행: (2025년 12월 28일 오후 03:42 GMT+9)
4 min read

Source: Hacker News

Finally in other languages

예외를 지원하는 많은 언어¹는 finally 절도 제공하므로 다음과 같이 쓸 수 있습니다.

try {
    // stuff
} finally {
    always();
}

간단히 살펴보면 이 제어 구조가 Java, C#, Python, JavaScript에는 존재하지만 C++에는 없습니다.

C++ approach

C++는 “우리는 tryfinally를 집에 두고 있다”고 말합니다.
C++에서 블록을 빠져나갈 때 코드를 실행하게 하려면 해당 코드를 소멸자에 넣어야 합니다. 소멸자는 블록을 떠날 때 실행되기 때문입니다. 이것이 Windows Implementation Library의 wil::scope_exit 함수가 사용하는 트릭입니다: 사용자가 제공한 람다를 소멸자에서 실행되는 사용자 정의 객체에 넣습니다.

auto ensure_cleanup = wil::scope_exit([&] { always(); });

/* stuff */

Exception‑handling quirks

원리는 동일하지만, 각 언어는 finally(또는 소멸자) 자체가 예외를 발생시킬 경우를 약간씩 다르게 처리합니다.

No exception in the guarded block

보호된 블록을 예외 없이 빠져나가면, finally 블록이나 소멸자에서 발생한 잡히지 않은 예외가 try 블록으로부터 발생한 것처럼 전파됩니다. 모든 언어가 이 점에 대해 동의하는 것으로 보입니다.

Exception in both the guarded block and the finally/destructor

LanguageBehavior when both the guarded block and the finally/destructor throw
Java, C#, Python, JavaScriptfinally 블록에서 발생한 예외가 원래 예외를 덮어쓰기 합니다; 원래 예외는 사라집니다. Update: Python 3.2에서는 원래 예외를 새로운 예외의 context 로 저장하지만, 여전히 새로운 예외가 전파됩니다.
C++다른 예외 때문에 소멸자가 실행 중일 때 소멸자에서 예외가 발생하면 프로그램이 종료됩니다.²

따라서 C++는 스코프를 떠날 때 코드를 실행할 수 있게 해 주지만, 그 코드가 예외를 탈출하게 하면 안 됩니다.

Footnotes

  1. Microsoft 컴파일러는 Structured Exception Handling을 위해 __try__finally 키워드도 지원합니다. 이는 C 코드를 위한 것이며, C++ 코드에서는 사용하지 말아야 합니다. 왜냐하면 C++ 예외와 때때로 혼란스러운 방식으로 상호 작용하기 때문입니다.
  2. 이것이 wil::scope_exit이 람다에서 예외가 발생하면 프로세스를 종료한다는 문서를 포함하는 이유입니다. 람다에서 발생한 예외를 기록하고 무시하는 대체 함수 wil::scope_exit_log도 있습니다. Java와 같은 동작을 제공하는 변형은 없습니다.
Back to Blog

관련 글

더 보기 »