As of C++11, it is an error to throw from a destructor without declaring it throwing explicitly.
1 2 3 4
|
prog.cc: In destructor 'base::~base()':
prog.cc:11:15: warning: throw will always call terminate() [-Wterminate]
11 | throw 42;
| ^~
|
which is why when this program runs, it terminates unconditionally.
If you make your destructor throwing (
~base() noexcept(false) { throw 42; }
),. you will still terminate because the destructor of B will be called during exception handling to handle
throw 32;
, and throwing an exception while unwinding for another is termination.
You can make it compile and run if you end the lifetime of B before reaching throw 32:
1 2 3 4
|
try {
base{};
throw 32;
}
|
demo
https://wandbox.org/permlink/1fyWsOnfF8KYLBxK
or if you handle the 32 before ending the lifetime of B
1 2 3 4 5 6
|
try {
base B;
try {
throw 32;
} catch(int y) { cout << y; }
}
|
demo
https://wandbox.org/permlink/wDPtf9ToPSxqX73y
in general, throwing from destructors is considered to be a bad idea and is used very rarely (I know only 3 libraries that do: SOCI, galera, and boost.log)