Namespaces
Variants

std:: set_terminate

From cppreference.net
Определено в заголовочном файле <exception>
(до C++11)
(начиная с C++11)

Устанавливает f новой глобальной функцией обработчика завершения и возвращает ранее установленный std::terminate_handler . f должна завершать выполнение программы без возврата к вызывающей стороне, иначе поведение не определено.

Данная функция является потокобезопасной. Каждый вызов std::set_terminate синхронизируется-с (см. std::memory_order ) последующими вызовами std::set_terminate и std::get_terminate .

(начиная с C++11)

Содержание

Параметры

f - указатель на функцию типа std::terminate_handler , или нулевой указатель

Возвращаемое значение

Ранее установленный обработчик завершения, или нулевой указатель, если обработчик не был установлен.

Пример

#include <cstdlib>
#include <exception>
#include <iostream>
int main()
{
    std::set_terminate([]()
    {
        std::cout << "Unhandled exception\n" << std::flush;
        std::abort();
    });
    throw 1;
}

Возможный вывод:

Unhandled exception
bash: line 7:  7743 Aborted                 (core dumped) ./a.out

Обработчик завершения также будет работать для запущенных потоков, поэтому его можно использовать в качестве альтернативы оборачиванию функции потока в блок try / catch . В следующем примере, поскольку исключение не обрабатывается, std::terminate будет вызван.

#include <iostream>
#include <thread>
void run()
{
    throw std::runtime_error("Thread failure");
}
int main()
{
    try
    {
        std::thread t{run};
        t.join();
        return EXIT_SUCCESS;
    }
    catch (const std::exception& ex)
    {
        std::cerr << "Exception: " << ex.what() << '\n';
    }
    catch (...)
    {
        std::cerr << "Unknown exception caught\n";
    }
    return EXIT_FAILURE;
}

Возможный вывод:

terminate called after throwing an instance of 'std::runtime_error'
  what():  Thread failure
Aborted (core dumped)

С введением обработчика завершения, исключение, выброшенное из неосновного потока, может быть проанализировано, и выход может быть выполнен корректно.

#include <iostream>
#include <thread>
class foo
{
public:
    foo() { std::cerr << "foo::foo()\n"; }
    ~foo() { std::cerr << "foo::~foo()\n"; }
};
// Статический объект, ожидается вызов деструктора при выходе
foo f;
void run()
{
    throw std::runtime_error("Thread failure");
}
int main()
{
    std::set_terminate([]()
    {
        try
        {
            std::exception_ptr eptr{std::current_exception()};
            if (eptr)
            {
                std::rethrow_exception(eptr);
            }
            else
            {
                std::cerr << "Exiting without exception\n";
            }
        }
        catch (const std::exception& ex)
        {
            std::cerr << "Exception: " << ex.what() << '\n';
        }
        catch (...)
        {
            std::cerr << "Unknown exception caught\n";
        }
        std::exit(EXIT_FAILURE);
    });
    std::thread t{run};
    t.join();
}

Вывод:

foo::foo()
Exception: Thread failure
foo::~foo()

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

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