Tuesday 15 October 2013

C++ Class destructor throwing an exception ... No No

In C++ exception handling is feature provided by the C++ run-time environment to handle errors in execution of functions.
Exceptions are helpful if the code which handles error or failure happening in a function is different than the one which calls the function.
C++ allows exceptions using the try, throw and catch constructs provided by the language.
Technically any of the users class member functions can throw an exception if it faces any error or failure in some operation like- memory allocation, dynamic type casting.
It is a bad practice  to have a user defined destructor throw an exception. It could cause many issues in the program and system, few of which listed below -

1] C++ run-time aborts the execution of the program if there are two exceptions throw from same function as it does not know which one to catch -
  So if a destructor which throws is invoked when a local class object
 goes out of scope on end of a function which happens on the account of a exception thrown from the function, the catch block in the hierarchy cannot catch two exceptions and program terminates.

2] A destructor throwing an exception could cause memory leaks in the system due to freeing up of memory not happening -
 If a user has  his classes and objects ,then it could have the 'new' and 'delete' operators overloaded for his class.
 When a dynamically allocated user defined class object is deleted,  first the destructor of the class is invoked and then it invokes the delete operator function.
 But since this destructor throws an exception, the delete operator function is never executed and memory allocated in new operator function is never freed and it leaks memory.

Below cooked up example code demonstrates this behavior.

On compiling this below code using g++ and executing on a Linux it's output is as shown :

Inside constructor
Inside my()
operator new called
Inside constructor
inside try , before deleting pBomb
Inside destructor
caught exception from destructor
Inside my() Before throw no boom
terminate called after throwing an instance of 'char const*'
Aborted


#include "iostream"  
 #include "string"   
 #include "stdlib.h"  
 class Bomb { // bad class throws exception from destructor  
   int x;  
 public:  
   Bomb() : x(0) {std::cout << "Inside constructor\n" ;}  
   ~Bomb() { std::cout << "Inside destructor\n"; throw "boom"; }  
   void * operator new(size_t n) throw() //This function does not throw  
   {  
     std::cout << "operator new called\n" ;  
     return malloc(n);  
   }  
   void operator delete(void *p) throw() //This function does not throw  
   {  
     std::cout << "operator delete called\n" ; // never gets here  
     if (p != 0) free(p);  
   }  
 };  
 void my() { //This function throws std::string  
   Bomb myBomb; // local variable that will go out of scope when code exits this function  
   std::cout << "Inside my()\n";  
   Bomb *pBomb = new Bomb();  
   try {  
     std::cout << "inside try , before deleting pBomb\n" ;  
     delete pBomb;  
   } catch (...) {  
     // Gets here but leaks storage. Print output shows that  
     // operator new was called but operator delete was not.  
     std::cout << "caught exception from destructor\n";  
   }  
   // program dies here: can't throw two exceptions  
   // ("boom" and "no boom") at the same time.  
   std::cout << "Inside my() Before throw no boom\n";  
   throw "no boom"; // program dies here  
   std::cout << "Inside my() After throw no boom\n";  
 }  
 int main(int argc, char **argv)  
 {  
   try {  
     my();  
   } catch (std::string message) {  
     std::cout << "function my() threw %s\n", message; // This is never printed as program terminates before reaching here  
   }  
 }