Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/error/set terminate"

From cppreference.com
< cpp‎ | error
(Use std::endl, since abort may not allow std::cout to flush.)
m (fmt)
 
(6 intermediate revisions by 6 users not shown)
Line 2: Line 2:
 
{{cpp/error/navbar}}
 
{{cpp/error/navbar}}
 
{{dcl begin}}
 
{{dcl begin}}
{{dcl header | exception}}
+
{{dcl header|exception}}
 
{{dcl rev multi|until1=c++11
 
{{dcl rev multi|until1=c++11
 
|dcl1=
 
|dcl1=
Line 11: Line 11:
 
{{dcl end}}
 
{{dcl end}}
  
Makes {{tt|f}} the new global terminate handler function and returns the previously installed {{lc|std::terminate_handler}}.
+
Makes {{c|f}} the new global terminate handler function and returns the previously installed {{lc|std::terminate_handler}}. {{c|f}} shall terminate execution of the program without returning to its caller, otherwise the behavior is undefined.
  
 
{{rrev|since=c++11|
 
{{rrev|since=c++11|
This function is thread-safe. Every call to {{tt|std::set_terminate}} ''synchronizes-with'' (see {{lc|std::memory_order}}) the subsequent {{tt|std::set_terminate}} and {{lc|std::get_terminate}}
+
This function is thread-safe. Every call to {{tt|std::set_terminate}} ''synchronizes-with'' (see {{lc|std::memory_order}}) subsequent calls to {{tt|std::set_terminate}} and {{lc|std::get_terminate}}.
 
}}
 
}}
  
 
===Parameters===
 
===Parameters===
 
{{par begin}}
 
{{par begin}}
{{par | f | pointer to function of type {{lc|std::terminate_handler}}, or null pointer}}
+
{{par|f|pointer to function of type {{lc|std::terminate_handler}}, or null pointer}}
 
{{par end}}
 
{{par end}}
  
Line 26: Line 26:
  
 
===Example===
 
===Example===
{{example|code=
+
{{example
#include <iostream>
+
|code=
 
#include <cstdlib>
 
#include <cstdlib>
 
#include <exception>
 
#include <exception>
 
+
#include <iostream>
 +
 
 
int main()
 
int main()
 
{
 
{
     std::set_terminate([](){ std::cout << "Unhandled exception" << std::endl; std::abort();});
+
     std::set_terminate([]()
 +
    {
 +
        std::cout << "Unhandled exception\n" << std::flush;
 +
        std::abort();
 +
    });
 
     throw 1;
 
     throw 1;
 
}
 
}
Line 40: Line 45:
 
Unhandled exception
 
Unhandled exception
 
bash: line 7:  7743 Aborted                (core dumped) ./a.out
 
bash: line 7:  7743 Aborted                (core dumped) ./a.out
 +
}}
 +
 +
The terminate handler will also work for launched threads, so it can be used as an alternative to wrapping the thread function with a {{c/core|try}}/{{c/core|catch}} block. In the following example, since the exception is unhandled, {{lc|std::terminate}} will be called.
 +
 +
{{example
 +
|code=
 +
#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;
 +
}
 +
|p=true
 +
|output=
 +
terminate called after throwing an instance of 'std::runtime_error'
 +
  what():  Thread failure
 +
Aborted (core dumped)
 +
}}
 +
 +
With the introduction of the terminate handler, the exception thrown from the non-main thread can be analyzed, and exit can be gracefully performed.
 +
 +
{{example
 +
|code=
 +
#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();
 +
}
 +
|output=
 +
foo::foo()
 +
Exception: Thread failure
 +
foo::~foo()
 
}}
 
}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/error/dsc terminate}}
+
{{dsc inc|cpp/error/dsc terminate}}
{{dsc inc | cpp/error/dsc get_terminate}}
+
{{dsc inc|cpp/error/dsc get_terminate}}
{{dsc inc | cpp/error/dsc terminate_handler}}
+
{{dsc inc|cpp/error/dsc terminate_handler}}
 
{{dsc end}}
 
{{dsc end}}
  
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}

Latest revision as of 10:28, 9 July 2024

 
 
 
Defined in header <exception>
(until C++11)
std::terminate_handler set_terminate( std::terminate_handler f ) noexcept;
(since C++11)

Makes f the new global terminate handler function and returns the previously installed std::terminate_handler. f shall terminate execution of the program without returning to its caller, otherwise the behavior is undefined.

This function is thread-safe. Every call to std::set_terminate synchronizes-with (see std::memory_order) subsequent calls to std::set_terminate and std::get_terminate.

(since C++11)

Contents

[edit] Parameters

f - pointer to function of type std::terminate_handler, or null pointer

[edit] Return value

The previously-installed terminate handler, or a null pointer value if none was installed.

[edit] Example

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

Possible output:

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

The terminate handler will also work for launched threads, so it can be used as an alternative to wrapping the thread function with a try/catch block. In the following example, since the exception is unhandled, std::terminate will be called.

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

Possible output:

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

With the introduction of the terminate handler, the exception thrown from the non-main thread can be analyzed, and exit can be gracefully performed.

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

Output:

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

[edit] See also

function called when exception handling fails
(function) [edit]
obtains the current terminate_handler
(function) [edit]
the type of the function called by std::terminate
(typedef) [edit]