Bloomberg LP Interview Question
Software Engineer / DevelopersIt is good practice to throw and catch exception in destructors. You better catch or else they propagate and may terminate a running program.
Check Meyers's More Effective C++ for explanation.
Exception are common in constructors as well but be careful when to use them since they are expensive.
You cannot throw an exception from a destructor. It's not allowed in C++. However, you can throw an exception from a constructor since it does not have a return type.
By not allowed, I meant that the compiler will not be able to decide what to do with the exception.
It's allowed. Just try it.
The problem will be when another (or the same but for another object) destructor throws an exception during stack unwinding.
In terms of exception handling, destructors are special because they are the only functions get called during stack unwinding. NOTE: the compiler will not be able to decide what to do with TWO exceptions at the same time. ONE exception is perfectly ok.
Well... constructors of exception objects also can be invoked. The result will be the same: two exceptions => terminate().
I came across this page which had a detailed explanation.
"If during stack unwinding a destructor throws an exception and that exception is not handled, the terminate() function is called."
Code taken from the public library of IBM.
#include <iostream>
using namespace std;
struct E {
const char* message;
E(const char* arg) : message(arg) { }
};
void my_terminate() {
cout << "Call to my_terminate" << endl;
};
struct A {
A() { cout << "In constructor of A" << endl; }
~A() {
cout << "In destructor of A" << endl;
throw E("Exception thrown in ~A()");
}
};
struct B {
B() { cout << "In constructor of B" << endl; }
~B() { cout << "In destructor of B" << endl; }
};
int main() {
set_terminate(my_terminate);
try {
cout << "In try block" << endl;
A a;
B b;
throw("Exception thrown in try block of main()");
}
catch (const char* e) {
cout << "Exception: " << e << endl;
}
catch (...) {
cout << "Some exception caught in main()" << endl;
}
cout << "Resume execution of main()" << endl;
}
Output :
In try block
In constructor of A
In constructor of B
In destructor of B
In destructor of A
Call to my_terminate
Throw is called in the destructor of A which isn't handled, so the program calls terminate.
A C++ destructor throws or may throw an exception.
C++ destructors should never throw exceptions for two reasons. First, C++ objects can be torn down implicitly in contexts, where exceptions cannot be allowed. For example, suppose you enter a block and declare an instance of an object X whose destructor will throw an exception E1. Now suppose you exit that block by throwing another exception, E2. The C++ runtime cannot execute the exception handlers for both E1 and E2, and choosing one would effectively lose the other exception. Since losing exceptions is unacceptable, the C++ runtime calls terminate() which normally kills the process immediately.
Second, even if an exception thrown by a destructor is successfully thrown and caught, it is still bad because it causes the application to leak memory. When an object is deleted, two things happen: first the destructor is called and second the delete operator is called. It is the delete operator that actually releases the storage. If the destructor throws an exception the delete operator is never called so you will leak memory.
software.intel.com/sites/products/documentation/doclib/iss/2013/sa-ptr/sa-ptr_win_lin/GUID-D2983B74-74E9-4868-90E0-D65A80F8F69F.htm
The only way to catch an error in constructors is by using exceptions.
- Kiran April 26, 2010Exception from destructor is illegal. If destruction is happening in an exception, and if this destructor throws an exception, result becomes undefined.