140 likes | 244 Views
An exception. An exception is a situation that does not allow the normal, sequential continuation of the code. Examples: invalid or Null pointer dereference array index out of bounds file does not exist hardware I/O error arithmetic error ( divide by 0, √-1 ) out of memory.
E N D
An exception • An exception is a situation that does not allow the normal, sequential continuation of the code. • Examples: • invalid or Null pointer dereference • array index out of bounds • file does not exist • hardware I/O error • arithmetic error ( divide by 0, √-1 ) • out of memory
Two schools • An exception is something really exceptional and unexpected, very unlikely to occur in the day-to-day use of the application. • Appropriate when the exception mechanism is unreliable, difficult to use or read, or very expensive in memory and/or execution time. • An exception is simply something that is easier to program using the exception mechanism. • An exception is just ‘an alternative way of returning’. When a function can’t return something from its normal domain, it throws an exception.
Manual exception handling (C) • An exception can be handled by ‘normal’ code: • Test the condition. • Return an error flag or error code. buffer *p1 = malloc( sizeof( buffer )); if( p1 == 0 ){ return out_of_memory_error_code; } buffer *p2 = malloc( sizeof( buffer )); if( p2 == Null ){ return out_of_memory_error_code; } It is not easy to handle exceptions corrcetly. What is wrong in the (C) example? (hint: memory leak)
What to do? • Do nothing – pray that it will never occur. • Application abort • When the condition is not met, abort the application with an appropriate error message. (assert, call abort() ) • Continuation model • Call some ‘repair’ function, when it is done assume the situation has been repaired. Restart the operation and continue as if nothing had happened. (for repairable problems, like a page fault) • Abort model • Halt the current line of execution, search for the next ‘higher’ level that can handle the situation, continue after that handler. (all modern programming languages)
Do nothing – you must be kidding?? If he made cars only the prototypes would have safety belts, airbags, and ABS…
C++ abort mechanism overview Error detected, but this code does not know what to do. int divide( int c, int d ){ if( d == 0 ){ throw divide_by_zero; } return c / d; } void calculate( ){ try { p = divide( 3, q ) – divide( 9, ( b +5 )); } catch divide_by_zero { p = 0x77; } } Anticipate a problem. Take action appropriate for this situation. When no ‘catch’ is present for the exception abort the application.
Throwing an exception class stupid_mistake : public exception { stupid_mistake( char *description ); . . . } throw stupid_mistake( ”not implemented yet” ); • An exception is just some expression. • You can define your own exception class(es). • The throw statement invokes the creator! • It often makes sense to add some ‘extra information’ for instance for logging. This info must be provided to the constructor called in the throw statement.
Throwing an exception // nodig voor excepties #include <stdexcept> using namespace std; Vector::Vector (int first_index, int n) : i1 (first_index), num (n) { if( num < 0 ){ throw invalid_argument (“Vector: num < 0”); } pVec = new int[num]; } A better way of handling a <0 size vector. (What would be even better?)
An exception can be an object By convention, exceptions derive from ‘exception’. An exception classes tree makes it possible to handle a sub-class of exception in a uniform manner.
Catching an exception try { statements; } catch( parameter1 ){ statements1; } catch( parameter2 ){ statements2; } • When an exception is thrown in statements (or in code called by statements) • If the exception is acceptable for parameter1 then statements1 are executed and the exception is handled. • Likewise for parameter2 and statements2. • If none of the catch blocks match the exception then the exception is propagated up (as if the catch blocks were not there at all).
Catching an exception Try { . . . } except( stupid_mistake m ){ cout << ”Sorry, my mistake:\n” cout << m.message() << ”\n”; asert( 0 ); } The exception handler is like a function, called with the exception value as parameter. You can use the exception object, probably to find out what happened. Try { . . . } except( ... ){ cout << ”I have no idea what happened\n” asert( 0 ); } As a last resort, you can catch ‘…’. But then you don’t get the exception value
Example // file FileError.h #include <stdexcept> using namespace std; class file_error : public runtime_error { public: file_error( const char * what ): runtime_error ( what ){} }; void openFile (const char * fname, ifstream & inFile); #include <fstream> #include <iostream> #include <iomanip> #include ”FileError.h” void openFile (const char * fname, ifstream & inFile){ inFile.open( fname ); if( !inFile ){ // Clear state of file object! inFile.clear(); throw file_error ("Can’t open file."); } }
Example #include ”FileError.h” void main( void ){ char fileName[ 80 ]; ifstream inFile; bool open = false; int n = 0; do{ cout << "Enter filename: "; cin >> setw( 80 ) >> fileName; try { openFile( fileName, inFile ); open = true; } catch( file_error fe ){ cout << fe.what() << endl; n += 1; } } while( !open && n < 3 ); if( open ){ cout << fileName << " opened for reading.\n“; inFile.close(); } } >> is used for formatted input.