Why isn't the function called unexpectedly?

I expect the following code to call my unexpected handler, but the terminate handler is called instead:

#include <except>
#include <iostream>

void my_terminate() {
    std::cerr << "my terminate handler";
    std::exit(0);
}

void my_unexpected() {
    std::cerr << "my unexpected handler";
    std::exit(EXIT_FAILURE);
}

#pragma argsused
int main(int argc, char* argv[])
{
    std::set_terminate(my_terminate);
    std::set_unexpected(my_unexpected);
    try {
        throw std::exception();
    } catch (const std::logic_error&) {
    }
    return 0;
}

      

The C ++ Builder 6 Developer's Guide explicitly encourages installing custom unexpected handlers via set_unexpected()

. What am I doing wrong, or is this just a bug in C ++ - Builder 6?

+3


source to share


2 answers


The callback handler std::set_unexpected

(for std::unexpected

) will be called when an unexpected exception is thrown; when no exception is being handled. An unexpected handler is called when the dynamic exception specification is violated .

As an example:

void my_terminate() {
    std::cerr << "my terminate handler";
    std::exit(0);
}

void my_unexpected() {
    std::cerr << "my unexpected handler";
    std::exit(EXIT_FAILURE);
}

void function() throw() // no exception in this example, but it could be another spec
{
    throw std::exception();
}

int main(int argc, char* argv[])
{
    std::set_terminate(my_terminate);
    std::set_unexpected(my_unexpected);
    try {
        function();
    } catch (const std::logic_error&) {
    }
    return 0;
}

      



Output signal

my unexpected handler

The handler set std::set_terminate

is called std::terminate

(for the numerous reasons listed in the link). Interestingly, the default behavior when an exception is thrown but not caught is invocationstd::terminate

.

+10


source


When an uncaught exception occurs, thrown . terminate

int main()
{
    throw 1; // terminate
}

      

Thrown when an unexpected exception occurs . unexpected

void foo() throw(int)
{
    throw "unexpected will be called.";
}

int main()
{
    foo();
}

      



I'll show you an example of a program that ends up / unexpectedly:

#include <cstdlib>
#include <iostream>
#include <exception>

#define TEST_TERMINATE

void my_terminate()
{
    std::cout << "terminate!" << std::endl;
    std::abort();
}
void my_unexpected()
{
    std::cout << "unexpected!" << std::endl;
    std::abort();
}

void foo() throw(int)
{
    throw "unexpected will be called.";
}

int main()
{
    std::set_terminate(my_terminate);
    std::set_unexpected(my_unexpected);

#ifdef TEST_TERMINATE
    throw 1;
#else
    foo();
#endif
}

      

(live example to complete , unexpectedly )

+2


source







All Articles