Namespaces
Variants

std:: set_terminate

From cppreference.net
Défini dans l'en-tête <exception>
(jusqu'à C++11)
(depuis C++11)

Fait de f la nouvelle fonction globale de gestion de terminaison et retourne le précédent std::terminate_handler installé. f doit terminer l'exécution du programme sans retourner à son appelant, sinon le comportement est indéfini.

Cette fonction est sûre dans un contexte multithread. Chaque appel à std::set_terminate synchronise-avec (voir std::memory_order ) les appels ultérieurs à std::set_terminate et std::get_terminate .

(depuis C++11)

Table des matières

Paramètres

f - pointeur vers une fonction de type std::terminate_handler , ou pointeur nul

Valeur de retour

Le gestionnaire de terminaison précédemment installé, ou une valeur de pointeur nul si aucun n'était installé.

Exemple

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

Sortie possible :

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

Le gestionnaire de terminaison fonctionnera également pour les threads lancés, il peut donc être utilisé comme alternative à l'encapsulation de la fonction de thread avec un bloc try / catch . Dans l'exemple suivant, puisque l'exception n'est pas gérée, std::terminate sera appelé.

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

Sortie possible :

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

Avec l'introduction du gestionnaire de terminaison, l'exception levée depuis le thread non principal peut être analysée, et la sortie peut être effectuée de manière gracieuse.

#include <iostream>
#include <thread>
class foo
{
public:
    foo() { std::cerr << "foo::foo()\n"; }
    ~foo() { std::cerr << "foo::~foo()\n"; }
};
// Objet statique, destructeur attendu à la sortie
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();
}

Sortie :

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

Voir aussi

fonction appelée lorsque la gestion des exceptions échoue
(fonction)
obtient le terminate_handler actuel
(fonction)
le type de la fonction appelée par std::terminate
(typedef)