std::uncaught_exception, std::uncaught_exceptions
| Определён в заголовке <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) (constexpr начиная с C++26) |
std::uncaught_exception обнаруживает, выполняется ли в данный момент раскрутка стека.Иногда безопасно выбрасывать исключение, даже если std::uncaught_exception() == true(до C++17) std::uncaught_exceptions() > 0(начиная с C++17). Например, если раскрутка стека приводит к уничтожению объекта, деструктор этого объекта может выполнить код, который выбрасывает исключение, при условии, что исключение будет перехвачено каким-либо блоком catch до выхода из деструктора.
Возвращаемое значение
true если в настоящее время в этом потоке выполняется раскрутка стека, false в противном случае.Примечания
Примером использования возвращающей 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 issue 47: Uncaught Exceptions (Необработанные исключения) |
| 2. | Обоснование для std::uncaught_exceptions (N4125)
|