Reputation: 141
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
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. 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
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
orstd::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