std::uncaught_exception, std::uncaught_exceptions — cppreference.com
Материал из cppreference.com
<tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody>
| Определено в заголовочном файле |
||
| (1) | ||
|
|
(до C++11) | |
|
|
(начиная с C++11) (устарело в C++17) (удалено в C++20) |
|
|
|
(2) | (начиная с C++17) |
1) Определяет, есть ли в текущем потоке активный объект исключения, т.е. исключение было сгенерировано или повторно сгенерировано и ещё управление не вошло в соответствующее предложение catch, std::terminate или std::unexpected. Другими словами, std::uncaught_exception определяет, выполняется ли в данный момент раскручивание стека.
2) Определяет, сколько исключений в текущем потоке было сгенерировано или повторно сгенерировано, и которые ещё не вошли в соответствующие им предложения catch.
Иногда генерировать исключение безопасно, даже если std::uncaught_exception() == true. Например, если раскручивание стека приводит к уничтожению объекта, деструктор для этого объекта может запускать код, который генерирует исключение, если исключение перехватывается каким-либо блоком 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
|
Пример
#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()
|