Namespaces
Variants

std::uncaught_exception, std::uncaught_exceptions

С сайта ru.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)
(constexpr начиная с C++26)
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()

Смотрите также

функция, вызываемая при сбое обработки исключений
(функция)
тип разделяемого указателя для обработки объектов исключений
(typedef)
захватывает текущее исключение в std::exception_ptr
(функция)

Внешние ссылки

1.  GOTW issue 47: Uncaught Exceptions (Необработанные исключения)
2.  Обоснование для std::uncaught_exceptions (N4125)