std::uncaught_exception, std::uncaught_exceptions

Header: <exception>

  1. Detects if the current thread has a live exception object, that is, an exception has been thrown or rethrown and not yet entered a matching catch clause, std::terminate or std::unexpected. In other words, std::uncaught_exception detects if stack unwinding is currently in progress.

# Declarations

bool uncaught_exception() throw();

(until C++11)

bool uncaught_exception() noexcept;

(since C++11) (deprecated in C++17) (removed in C++20)

int uncaught_exceptions() noexcept;

(since C++17) (constexpr since C++26)

# Notes

An example where int-returning uncaught_exceptions is used is the boost.log library: the expression BOOST_LOG(logger) « foo(); first creates a guard object and records the number of uncaught exceptions in its constructor. The output is performed by the guard object’s destructor unless foo() throws (in which case the number of uncaught exceptions in the destructor is greater than what the constructor observed).

std::experimental::scope_fail and std::experimental::scope_success in LFTS v3 rely on the functionality of uncaught_exceptions, because their destructors need to do different things that depend on whether is called during stack unwinding.

# Example

#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';
    }
}

# Defect reports

DRApplied toBehavior as publishedCorrect behavior
LWG 70C++98the exception specification of uncaught_exception() was missingspecified as throw()

# See also