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 перед выходом из деструктора.
Содержание |
[править]Параметры
(нет)
[править]Возвращаемое значение
[править]Примечание
Примером, где используется возвращающая 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";throwstd::runtime_error("тестовое исключение");}catch(conststd::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) |