std::uncaught_exception, std::uncaught_exceptions
| Определено в заголовочном файле <exception>
|
||
| (1) | ||
bool uncaught_exception() throw(); |
(до C++11) | |
bool uncaught_exception() noexcept; |
(начиная с C++11) (устарело в C++17) (удалено в C++20) |
|
int uncaught_exceptions() noexcept; |
(2) | (начиная с C++17) |
std::uncaught_exception определяет, выполняется ли в данный момент раскручивание стека.Иногда генерировать исключение безопасно, даже если std::uncaught_exception() == true. Например, если раскручивание стека приводит к уничтожению объекта, деструктор для этого объекта может запускать код, который генерирует исключение, если исключение перехватывается каким-либо блоком 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
|
Пример
#include <exception>
#include <iostream>
#include <stdexcept>
struct Foo
{
char id{'?'};
int count = std::uncaught_exceptions();
~Foo()
{
count == std::uncaught_exceptions()
? std::cout << id << ".~Foo() вызван нормально\n"
: std::cout << id << ".~Foo() вызван во время раскручивания стека\n";
}
};
int main()
{
Foo f{'f'};
try
{
Foo g{'g'};
std::cout << "Сгенерировано исключение\n";
throw std::runtime_error("тестовое исключение");
}
catch (const std::exception& e)
{
std::cout << "Исключение поймано: " << e.what() << '\n';
}
}
Возможный вывод:
Сгенерировано исключение
g.~Foo() вызван во время раскручивания стека
Исключение поймано: тестовое исключение
f.~Foo() вызван нормально
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 70 | C++98 | спецификация исключения uncaught_exception() отсутствовала
|
указывается как throw()
|
Смотрите также
| функция, вызываемая при сбое обработки исключения (функция) | |
(C++11) |
тип общего указателя для обработки объектов исключений (определение типа) |
(C++11) |
фиксирует текущее исключение в std::exception_ptr (функция) |
Внешние ссылки
| 1. | Проблема GOTW 47: Неперехваченные Исключения |
| 2. | Обоснование std::uncaught_exceptions (N4125)
|