Spec-Zone.ru › C++

std::set_terminate

Определён в заголовочном файле <exception>
std::terminate_handler set_terminate( std::terminate_handler f ) throw();
(до C++11)
std::terminate_handler set_terminate( std::terminate_handler f ) noexcept;
(начиная с 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"; }
};

// Static object, expecting destructor on exit
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()

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/error/set_terminate

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API