Docstoc

Exception Handling

Document Sample
Exception Handling Powered By Docstoc
					Exception Handling



        1
       What is an Exception?
• Any event outside the bounds of routine
  behavior.

• Some typical examples:

 • Error conditions (ie iterator/offset out of
   bounds)

 • Unexpected data format

 • Memory management failures

                      2
            Handling Problems
    Return a special error value
     T* error = “some error code”;
     if(iter < 0 || iter >= maxSize)
       return *error;
     return mat[iter];


    But what happens here?
    x = v[2] + v[4]; //not safe!
3
               Handling Problems
Just Die
  if(iter < 0 || iter >= maxSize)
    exit(1);
  return mat[iter];


Die Gracefully
  assert(iter < 0 && iter >= maxSize)
  return mat[iter];


Output when assert fails:
Assert.C:7: failed assertion `iter < 0 && iter >= 5'
Abort
  Why Use Exception
      handling?
• Many times you do not know what should
  be done if an error occurs.

• Solution:  Send notification and let the
  caller of your routine take responsibility.




                      5
  Exception Handling
• In C++, Exception Handling allows the
  programmer to notify the user when there
  is a problem.

• The problem can be handled in the
  notifying routine, or passed along to the
  caller.




                     6
    Exception Handling Facility

• The exception handling facility consists of
  two primary components:

 • Recognizing a problem and throwing an
    exception. (try - throw)

 • Eventual handling of the exception.
    (catch)


                      7
Simplistic overview:
int main(int argc, char* argv[])
{
string filename;
try{
     if(argc <= 1)
        throw “no command line arguments”;
     fin.open(argv[1]);
}
catch(string s){
   cout << “enter input filename “;
   cin >> filename;
   fin.open(filename.c_str());
}
//process data
                         8
            Throwing an
             Exception
 An exception is thrown using a throw statement.
Example:
throw 42;
throw “Panic message”;
throw IteratorOverflow(iter);
IteratorOverflow e(iter); throw e;


                        9
        throw Statement
•An exception (ie expression in a throw
statement) is an object of some type.
•Typically an exception is a class object of an
explicitly provided exception class or exception
class hierarchy.


   if(iter < 0 || iter >= maxSize)
      throw IteratorOverflow(iter, maxSize);   //class constructor
   return mat[iter];

                               10
class IteratorOverflow{
public:
         IteratorOverflow(int index, int max) :
                offset(index), bound(max) {}
        int getOffset() {return offset;}
        int getBound() {return maxSize;}
        void reset(){offset=0;}
        void message(ostream& os = cerr)
        {
             os << “Error: offset “ << offset <<
                    “ exceeds maximum bound “ << bound;
        }
private: int offset, bound;
};



                              11
         Nothing Exceptional About
            Exception Classes

An exception class hierarchy provides:
Storage for data that we wish to carry across function
calls.
Methods for displaying data and messages.

An exception object calls its message method to
display information from within a catch block.



                          12
            catch Blocks
•A program catches exceptions by their type using a
sequence of catch blocks.
A catch block consists of three parts:
   the keyword catch
   the declaration of a single type within
   parentheses
   a statement block




                         13
                      Example:
 catch(IteratorOverflow& iof){
         iof.message();          //message writes to cerr
         iof.message(log);       //log is iostream object
         iof.reset()             //or something …
 }
 continue;

•The type of the exception object that was thrown is compared against
the exception declaration of each catch block in turn. If the types
match, the statement block is executed.
•The above represents a complete handling of the exception. Normal
program execution continues with the first statement following the
catch block.

                                 14
      Re-throw Expression
It is often the case that we can not completely handle
an exception. If this is the case, we can re-throw the
exception.
  catch(IteratorOverflow &iof)(

         iof.message();           //message writes to cerr
         iof.message(log);        //log is iostream object
         throw;
  }

 •A re-throw can occur only within a catch block
 •The search for a matching catch block continues up the line
 •If complete handling in some catch block does not occur, the program
 aborts.
                                     15
               Catch all Block


catch(…)       //catch any and all exceptions
{
    cerr << “unknown exception thrown. GoodBye! “;
    //…
    exit(1);
}



                          16
            Exception Class Hierarchy

class MatrixException{
protected:
   virtual void diagnostic(){cout << "Matrix error\n";}
};

class SubscriptOutOfBoundsException : public MatrixException{
protected:
   void diagnostic(){cout << “Subscript out of bounds\n”;}
   void diagnostic(int r, int c){cout <<"out of bounds "<< r << c << endl;}
};

class SizeMismatchException : public MatrixException{
protected:
   void diagnostic(){cout << "binary op size mis-match\n";}
};

                                    17
                         Handlers

try{
       //some code that uses Matrix binary ops
   }
   catch(SizeMismatchException& e){ e.diagnostics();}
   catch(SubScriptsOutOfBounds& e){e.diagnostics(r,c);}
   catch(MatrixException& e){e.diagnostics();} //matches all Matrix..




                                     18
•
                 try Blocks keyword try
    A try block begins with the
    followed by a statement block.
•   Zero or more catch blocks follow the end
    of the try statement block.
•   If no exception is thrown within the try
    block, all catch blocks are ignored.
•   If an exception is thrown within the try
    block, a search for a matching catch block
    begins.
•   If no matching catch block is found,
    search continues up the call chain.
•   Program aborts if a matching catch is not
    found.
                      19
           Exception Handling
#include <iostream>            int main()
#include "Matrix.h"            {
#include "MatrixException.h"     funcHandlesIt();
using namespace std;             funcPassItOn();
//function prototypes            funcCatchAll();
void func();                     func();
void funcHandlesIt();            cout << "Leaving Main\n";
void funcPassItOn();             return 0;
void funcCatchAll();           }




                                    20
            Example: Code not aware of
                     problem
                                     output:
                                     Constructing
void func() //func doesn’t care      0xbffffbf0
{                                    Constructing
  Matrix A(4,4), B(2,2);
  Matrix C(4,4);
                                     0xbffffc00
  C = A + B; //Exception thrown      Constructing
  //Control never reaches this point 0xbffffc10
  //Exception propagates             Abort
    //Search for matching catch block.
    //None found. Program aborts
    //Destructors not called.
}
                                 21
                Caller Handles Exception

                                        output:
void funcHandlesIt()                    Constructing 0xbffffc20
{                                       Constructing 0xbffffb80
  Matrix temp;                          Constructing 0xbffffb90
  try{                                  Constructing 0xbffffba0
     func();                            0xbffffba0 destructing matrix
  }                                      0xbffffb90 destructing matrix
  catch(MatrixException& e)              0xbffffb80 destructing matrix
  {                                      binary op size mis-match
    e.diagnostic();                     Leaving funcHandlesIt
  }                                     0xbffffc20 destructing matrix
  cout << “Leaving funcHandlesIt<<endl”; Leaving main
}
               Exception does not propagate
                                      22
           Caller Passes it on
void funcPassItOn()                        Constructing 0xbffffc20
{                                          Constructing 0xbffffb80
  Matrix temp;                             Constructing 0xbffffb90
  try{                                     Constructing 0xbffffba0
     func();                               0xbffffba0 destructing matrix
  }                                        0xbffffb90 destructing matrix
  catch(MatrixException& e)                0xbffffb80 destructing matrix
  {                                        Exception thrown
    cout << "Exception thrown\n";          Abort
    throw; //Exception Propagates
  }
  cout << "Leaving funcPassItOn\n";
}
                               What is missing here?
                                      23
                         Catch All
void funcCatchAll()                         output:
{                                           Constructing 0xbffffc20
  Matrix temp;                              Constructing 0xbffffb80
  try{                                      Constructing 0xbffffb90
     func();                                Constructing 0xbffffba0
  }                                         0xbffffba0 destructing matrix
  catch(...)                                 0xbffffb90 destructing matrix
  {                                          0xbffffb80 destructing matrix
    cout << "Exception thrown. Stops here\n";Exception thrown. Stops here
  }                                         Leaving funcCatchAll
  cout << "Leaving funcCatchAll\n";         0xbffffc20 destructing matrix
}                                            Leaving Main



                                     24
                        Review
•   A throw statement raises an exception
•   control propagates back to first catch block that matches
•   propagation follows the call chain
•   objects on stack are destroyed
•   throw exp;
•   throws object for matching
•   throw;
•   re-throws the exception being handled
•   valid only within a catch block
                                 25
             The Standard
              Exceptions

                           exception


bad_alloc   bad_cast   bad_typeid        runtime_error            logic_error


                             overflow_error        range_error   domain_error




                                    26
       bad_alloc Exception
Matrix *p = 0;
try{
       p = new Matrix;
   }
   catch( bad_alloc) {         //catch type, no object
        cout << “heap exhausted\n”;
        //…clean up and exit
   }
                         27
          exception Class

• exception is the base class.

• exception declares a virtual function
  named what().

• Classes derived from exception may
  define their own instance of what().

• class MatrixException : public
  exception{…}

                     28
            bad_alloc Exception
                               output:
Matrix *p = 0;                 *** malloc: vm_allocate(size=2211577856) failed
                               with 3
try{                           *** malloc[13737]: error: Can't allocate region
       p = new Matrix;         heap exhausted

   }
   catch( const bad_alloc& e) {
        e.what(); //what returns a const char*
        cout << “heap exhausted\n”;
        //…clean up and exit
   }
                                        29
   Benefits of Inheriting exception
• MatrixExceptions can be caught with

 • catch(const exception& ex)
   {cerr<<ex.what()<<endl;}

• No need to retrofit existing code to know about
  MatrixExceptions class.

• No need to use anonymous catch-all

• Must include <exception>
                         30
          Lab Exercise
Add exception handling to your Matrix class.
Replace all assert statements with throw
statements and test methods using try and catch
blocks. Write an MatrixException class
hierarchy:

				
DOCUMENT INFO