std::uncaught_exception, std::uncaught_exceptions
cppreference.net에서
| 헤더 <exception>
|
||
bool uncaught_exception() throw();
|
에 정의됨 (1) | (C++11까지) |
bool uncaught_exception() noexcept;
|
(C++11부터) (C++17에서 폐기됨) (C++20에서 제거됨) |
|
int uncaught_exceptions() noexcept;
|
(2) | (C++17부터) (C++26부터 constexpr) |
1) 현재 스레드에 활성 예외 객체가 있는지, 즉 예외가 발생하거나 다시 던져져서 일치하는 catch 절, std::terminate 또는 std::unexpected에 아직 진입하지 않았는지 감지합니다. 즉,
std::uncaught_exception은(는) 현재 스택 풀기가 진행 중인지 감지합니다.2) 현재 스레드에서 던져지거나 다시 던져져서 아직 일치하는 catch 절에 진입하지 않은 예외의 개수를 감지합니다.
때로는 std::uncaught_exception() == true(C++17까지) std::uncaught_exceptions() > 0(C++17부터)인 동안에도 예외를 던지는 것이 안전합니다. 예를 들어, 스택 풀기로 인해 객체가 소멸되는 경우, 해당 객체의 소멸자는 소멸자를 벗어나기 전에 예외가 일부 catch 블록에 의해 잡히기만 하면 예외를 던지는 코드를 실행할 수 있습니다.
반환값
1)
true 현재 스레드에서 스택 풀기가 진행 중이면 false, 그렇지 않으면 2) 현재 스레드에서 잡히지 않은 예외 객체의 개수.
참고 사항
int를 반환하는 uncaught_exceptions이(가) 사용되는 예는 boost.log 라이브러리입니다. 표현식 BOOST_LOG(logger) << foo();은(는) 먼저 가드 객체를 생성하고 생성자에서 잡히지 않은 예외의 개수를 기록합니다. 출력은 가드 객체의 소멸자에서 수행되며, foo()이(가) 예외를 던지지 않는 한(이 경우 소멸자에서 잡히지 않은 예외의 개수가 생성자가 관찰한 것보다 더 많음) 수행됩니다.
std::experimental::scope_fail 및 std::experimental::scope_success (LFTS v3)는 uncaught_exceptions의 기능에 의존합니다. 이들의 소멸자는 스택 풀기 중에 호출되는지 여부에 따라 다른 작업을 수행해야 하기 때문입니다.
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_lib_uncaught_exceptions |
201411L |
(C++17) | std::uncaught_exceptions
|
__cpp_lib_constexpr_exceptions |
202411L |
(C++26) | constexpr 예외 유형에 대해
|
예제
이 코드 실행
#include <exception>
#include <iostream>
#include <stdexcept>
struct Foo
{
char id{'?'};
int count = std::uncaught_exceptions();
~Foo()
{
count == std::uncaught_exceptions()
? std::cout << id << ".~Foo() called normally\n"
: std::cout << id << ".~Foo() called during stack unwinding\n";
}
};
int main()
{
Foo f{'f'};
try
{
Foo g{'g'};
std::cout << "Exception thrown\n";
throw std::runtime_error("test exception");
}
catch (const std::exception& e)
{
std::cout << "Exception caught: " << e.what() << '\n';
}
}
가능한 출력:
Exception thrown
g.~Foo() called during stack unwinding
Exception caught: test exception
f.~Foo() called normally
결함 보고서
다음 동작 변경 결함 보고서는 이전에 발행된 C++ 표준에 소급하여 적용되었습니다.
| DR | 적용 대상 | 발행된 동작 | 올바른 동작 |
|---|---|---|---|
| LWG 70 | C++98 | uncaught_exception()의 예외 명세가 누락됨
|
throw()
|
으로 지정됨더 보기
| 예외 처리 실패 시 호출되는 함수 (함수) | |
(C++11) |
예외 객체 처리를 위한 공유 포인터 타입 (typedef) |
(C++11) |
현재 예외를 std::exception_ptr 에 캡처 (함수) |
외부 링크
| 1. | GOTW 이슈 47: 잡히지 않은 예외 |
| 2. | std::uncaught_exceptions의 근거 (N4125) |