I am well aware of the fact that one should not throw any exception in destructor.
But as a part of making my grip on this concept,I coded this example :-
std::terminate will be called if an exception is thrown during stack unwinding. That means that if an exception is called while another exception is being handled, then std::terminate will be called.
In your example, that doesn't happen - A(); will construct and immediately destroy an instance of A. The throw 30 will then be caught correctly.
Changing your code to:
int main(){
try{
A a; // begin `a` lifetime
throw 10; // | throw #0
// | end `a` lifetime
// throw #1
}
catch(int i){
cout<<i<<endl;
cout<<"exception caught"<<endl;
}
}
will guarantee that std::terminate will be called. In this case, a will be destroyed and will throw while another exception is being handled.
live coliru example
Additional information:
cppreference/Destructors/Exceptions
StackOverflow: "throwing exceptions out of a destructor"
Note that in C++11 and above, your code snippet will call std::terminate and provide you a warning:
main.cpp: In destructor ‘A::~A()’:
main.cpp:16:15: warning: throw will always call terminate() [-Wterminate]
throw 30; ^~main.cpp:16:15: note: in C++11 destructors default to noexcept
terminate called after throwing an instance of 'int'
bash: line 7: 1505 Aborted (core dumped) ./a.out
As seen in the compiler output, since C++11 destructors are implicitly noexcept(true). If you want to prevent this behavior, you can simply mark them as noexcept(false). Example:
~A() noexcept(false)
{
throw 30;
}
live example on coliru
In your example, A() construct a temporary variable for A then destructs it immediately. Thus throw 10; is never executed.
The throw statement taking place is in the destructor for A. When executing A::~A(), the program is not unwinding (i.e. cleaning up state from an exception) at that point. See "Destructors that throw" for example.