STL programmer
STL programmer

Reputation: 141

Can anyone tell me when called terminate(), and when unexpected()?

What happens when ended function f() and g() ?

#include<iostream>
using namespace std;

class A
{
     ~A(){}

}
void f()
{
    cout << "terminate" << endl;

}
void g()
{
    cout << "unexpected" << endl;
}



int main()
{
    set_terminate(f);
    set_unexpected(g);
    throw 5;
    cout << "end" << endl;
    return 0;
}

Why is called abort() function? And when is called destruktor? I can't find logic :((((((((

Upvotes: 2

Views: 1070

Answers (2)

Alok Save
Alok Save

Reputation: 206528

The relevant rules are clearly defined in the standard, There are a number of rules but simply said and put the ones that apply to your example are:

  • throw without a catch results in call to terminate or the function set for it.
  • When a exception thrown does not match the exception specification results in a call to unexpected or the function set for it.

15.1 Throwing an exception
Para 8:

If no exception is presently being handled, executing a throw-expression with no operand calls terminate() (15.5.1).

15.4 Exception specifications
Para 8:

Whenever an exception is thrown and the search for a handler (15.3) encounters the outermost block of a function with an exception-specification, the function unexpected() is called (15.5.2) if the exceptionspecification does not allow the exception


Why does your program call abort?

Your program has an undefined behavior. It is compliant with the fact that you set the terminate_handler appropriately and as you notice the program does result in call to f() but the required behavior for a terminate_handler function is:

C++03 Standard 18.6.3.1.2:

A terminate_handler shall terminate execution of the program without returning to the caller.

Your terminate_handler function f does not satisfy this condition and hence results in Undefined behavior and technically it is possible that you can get any behavior, your implementation chooses to call abort in this situation. Nothing stops it from doing so.

Upvotes: 1

Andy Prowl
Andy Prowl

Reputation: 126432

Can anyone tell me when called terminate(), and when unexpected()?

In your case, your terminate handler will be invoked. You can verify this here.

Concerning std::terminate(), paragraph 15.5.1/1-2 contains a note which makes a pretty exhaustive list of the situation in which it is called (the part in bold font is what applies in your case):

1 In some situations exception handling must be abandoned for less subtle error handling techniques. [ Note: These situations are:

— when the exception handling mechanism, after completing the initialization of the exception object but before activation of a handler for the exception (15.1), calls a function that exits via an exception, or

when the exception handling mechanism cannot find a handler for a thrown exception (15.3), or

— when the search for a handler (15.3) encounters the outermost block of a function with a noexcept specification that does not allow the exception (15.4), or

— when the destruction of an object during stack unwinding (15.2) terminates by throwing an exception, or

— when initialization of a non-local variable with static or thread storage duration (3.6.2) exits via an exception, or

— when destruction of an object with static or thread storage duration exits via an exception (3.6.3), or

— when execution of a function registered with std::atexit or std::at_quick_exit exits via an exception (18.5), or

— when a throw-expression with no operand attempts to rethrow an exception and no exception is being handled (15.1), or

— when std::unexpected throws an exception which is not allowed by the previously violated dynamicexception- specification, and std::bad_exception is not included in that dynamic-exception-specification (15.5.2), or

— when the implementation’s default unexpected exception handler is called (D.11.1), or

— when the function std::nested_exception::rethrow_nested is called for an object that has captured no exception (18.8.6), or

— when execution of the initial function of a thread exits via an exception (30.3.1.2), or

— when the destructor or the copy assignment operator is invoked on an object of type std::thread that refers to a joinable thread (30.3.1.3, 30.3.1.4). —end note ]

2 In such cases, std::terminate() is called (18.8.3). [...]

Concerning std::unexpected(), per Paragraph 15.4/9:

Whenever an exception is thrown and the search for a handler (15.3) encounters the outermost block of a function with an exception-specification that does not allow the exception, then,

— if the exception-specification is a dynamic-exception-specification, the function std::unexpected() is called (15.5.2),

— otherwise, the function std::terminate() is called (15.5.1).

Upvotes: 3

Related Questions