1 159.234lecture 14 159.234 lecture 14 exception handling textbook p. 309-321

30
1 159.234 159.234 LECTURE 14 LECTURE 14 Exception Handling Exception Handling Textbook p. 309-321

Upload: deirdre-may

Post on 06-Jan-2018

218 views

Category:

Documents


0 download

DESCRIPTION

3 assert exit Rather than handling errors with assert - which just stops the program, or exit which also just stops the program, we can handle errors using the following keywords: try, catch and throw Exception Handling

TRANSCRIPT

Page 1: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

1

159.234159.234 LECTURE 14LECTURE 14Exception HandlingException Handling

Textbook p. 309-321

Page 2: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

2

ExceptionsExceptions are run-time errors that a program may detect.

Examples:• Division by 0Division by 0• Access to an array outside of its boundsAccess to an array outside of its bounds• Exhaustion of the free store memoryExhaustion of the free store memory

Exception HandlingException Handling

Page 3: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

3

Rather than handling errors with assertassert - which just stops the program, or exitexit which also just stops the program, we can handle errors using the following keywords:

• try, • catch and • throw

Exception HandlingException Handling

Page 4: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

4

Exception HandlingException Handling

main

f()

g()

h()

i()

Effect: Separate policy from mechanism

Routines g(), h(), and i() are removed from the run-time stack and their local variables are destructed.

Exception thrown by i() and caught by f()

Page 5: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

5

Using Using throwthrowWe use throwthrow to indicate an error:

//return the square root of a number entered from the keyboard//return the square root of a number entered from the keyboardint main(){ cout << "Enter a number: "; double x; cin >> x; //stop the program if the entered value is less than 0//stop the program if the entered value is less than 0 if (x < 0) throwthrow; // throws a default exception// throws a default exception cout << sqrt(x) << endl;}

In this example the thrown exception thrown exception is caught by the Operating Operating SystemSystem so it is effectively the same as an abortabort - it just stops the program.

Page 6: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

6

When the programmer does not specify an alternative action for the program to take in case an exception (error) occurs then:

• the terminate() terminate() function is invoked;

• this calls abort() abort() which stops the program.

Recall the behaviour of assert() assert() function.

Throwing an exceptionThrowing an exception

Page 7: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

7

ttryry{ if (d==0) { throwthrow "division by 0"; } cout << (N/d) << endl;}

catchcatch (const char* s){ // handle exceptions// handle exceptions cout << s; cout << " 1 used for divisor instead"; cout << " result = " << (N/1);}

Using Using try-catchtry-catch

Page 8: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

8

The trytry block is the part of the program we want to monitor for errors.

If an exception occurs, it is thrown using throwthrow.

The exception is caught--using catchcatch, and processed.

Once an exception has been thrown,

• control passes to the catchcatch expression and

• trytry block is terminated.

We sometimes describe the catchcatch clause as a “handler”

Exception HandlingException Handling

Page 9: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

9

More than one catchcatch can be associated with a trytry. different types different types of exceptions can be caught (e.g. int, char*, class, etc.)(e.g. int, char*, class, etc.)

A try try clause will have to be immediately followed by a catchcatch clause.

How How exceptionsexceptions are handled by are handled by catchcatch clauses?clauses?

Page 10: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

10

void Xhandler(int test){ try {

if (test) { throwthrow test; } else { throwthrow “Value is zero”;}

} catch (int iint i) {

cout << “Caught One!”; cout << “Value=” << i << endl;

} catch (const const charchar *str*str) {

cout << “Caught a string:”; cout << str << endl;

}}

Catch clausesCatch clauses

Page 11: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

11

int main(){

cout << "start\n";Xhandler(25);Xhandler(00);Xhandler(1);cout <<“end”;

}

Catch clausesCatch clauses

Page 12: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

12

IntVect::IntVect(int n=100): size(n){ if (n < 0) throwthrow(n); p = new int[size]; if(p == 0) throwthrow(“No memory”);

}

Order of Execution of Catch ClausesOrder of Execution of Catch Clauses

Constructor:

Page 13: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

13

int &IntVect :: operator[] (int i) { if ((i < 0)||(i >= size)) throwthrow(ii); return p[i];}

Order of Execution of Catch ClausesOrder of Execution of Catch Clauses

Overloaded operator[]

Page 14: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

14

void g(int n)g(int n) { try { IntVect aa(n); //...//... } catch(int jint j) {

cerr << “Size Error “ << n << endl; g(10);g(10); //retry g with legal size//retry g with legal size } catch(const const char *errorchar *error) { //do something//do something } catch(...) {

//do something//do something }} 

Order of Execution of Catch ClausesOrder of Execution of Catch Clauses

Page 15: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

15

catch(...) catch(...) is the syntax for catching everythingfor catching everything. A general purpose exception handling routine.

 

The catch handlers have to be listed in an orderlisted in an order that means they can all be called.

 

so catch(...)catch(...) must be at the end of the listend of the list.

Order of Execution of Catch ClausesOrder of Execution of Catch Clauses

Page 16: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

16

If a catch doesn’t manage to handle the error completely - then it may re-throwre-throw the exception:

catchcatch(int j) { if (j < 3) return; //to the end of try block

else throwthrow; // a throw without an operand passes the error up

// to next

} // enclosing block. 

The system catches all exceptions not handled by ussystem catches all exceptions not handled by us, with the function terminate()terminate() - which aborts the program.

Order of Execution of Catch ClausesOrder of Execution of Catch Clauses

Page 17: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

17

We can restrict the type of exceptions that a function can throw.

// This function can only throw ints, chars, // This function can only throw ints, chars, // and doubles.// and doubles.

void XhandlerXhandler(int test) throw(int, char, double) throw(int, char, double) {

if(test == 0) throwthrow (test); //with or without parenthesis is ok//with or without parenthesis is ok if(test == 1) throwthrow 'a'; if(test == 2) throwthrow 123.23;

}

Exception SpecificationsException Specifications

Page 18: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

18

int main(){

try{ Xhandler(0);

}

catch(int i) { cout << "Caught int\n";

}

catch(char c) { cout << "Caught char\n";

}

catch(double d) { cout <<"Caught double\n";

}}

Exception SpecificationsException SpecificationsException handling Exception handling implies a form of run-time type identification mechanism (RTTIRTTI), which may require some increase to code size, data size or both.

Page 19: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

19

#include <iostream>#include <exception>

using namespace std;

class CA{public:

CA() {cout << "CA ctor called." << endl;}~CA() {cout << "CA dtor called." << endl;}

};

class CB{public:

CB() {cout << "CB ctor called." << endl;}~CB() {cout << "CB dtor called." << endl;}

};

class CC{public:

CC() {cout << "CC ctor called." << endl;}~CC() {cout << "CC dtor called." << endl;}

};

CC *PCC = 0; //global pointer to CC

void func()func() throw(char *) {cout << "start of func()" << endl;CB B; //instance of CB

PCC = new CC; //create an instance

throw "exception message";cout << "you'll never see this" << endl;delete PCC;cout << "end of func()" << endl;

}int main() { cout << "beginning of main" << endl; try {

CA A; func();func(); cout << "end of try block." << endl;

} catchcatch(char *&errorMsg) {

cout << "handler: " << errorMsg << endl; delete PCC;

} catch(...) {

cout << "last handler: " << endl; delete PCC;

} cout << "\nend of main." << endl; return 0;}

Output: (using Visual C++)

beginning of mainCA ctor called.start of func()CB ctor called.CC ctor called.CB dtor called.CA dtor called.handler: exception messageCC dtor called.

end of main.Press any key to continue . . .

Unwinding of the stack caused by an exception

Exhandling.cpp

Page 20: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

20

CC *PCC = 0; //global pointer to CC

void func()func() throw(char *) {cout << "start of func()" << endl;CB B; //instance of CB

PCC = new CC; //create an instance

throw "exception message";cout << "you'll never see this" << endl;delete PCC;cout << "end of func()" << endl;

}int main() { cout << "beginning of main" << endl; try {

CA A; func();func(); cout << "end of try block." << endl;

} catchcatch(char *&errorMsg) {

cout << "handler: " << errorMsg << endl; delete PCC;

} catch(...) {

cout << "last handler: " << endl; delete PCC;

} cout << "\nend of main." << endl; return 0;}

Output: (using Visual C++)

beginning of mainCA ctor called.start of func()CB ctor called.CC ctor called.CB dtor called.CA dtor called.handler: exception messageCC dtor called.

end of main.Press any key to continue . . .

Unwinding of the stack caused by an exception

After the throw statement is called, func() is terminated first, destroying all local objects local objects and variablesvariables.

Next, the try block is also terminated, invoking the destruction of all local objects inside the block. Only then that the matching catch clause is executed.

As soon as the catch clause is done, the next statement appearing after the last catch clause is executed.

Exhandling.cpp

Page 21: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

21

CC *PCC = 0; //global pointer to CC

void func()func() throw(char *) {cout << "start of func()" << endl;CB B; //instance of CB

PCC = new CC; //create an instance

throw "exception message";cout << "you'll never see this" << endl;delete PCC;cout << "end of func()" << endl;

}int main() { cout << "beginning of main" << endl; try {

CA A; func();func(); cout << "end of try block." << endl;

} catchcatch(char *&errorMsg) {

cout << "handler: " << errorMsg << endl; delete PCC;

} catch(...) {

cout << "last handler: " << endl; delete PCC;

} cout << "\nend of main." << endl; return 0;}

Output: (using Visual C++)

beginning of mainCA ctor called.start of func()CB ctor called.CC ctor called.CB dtor called.CA dtor called.handler: exception messageCC dtor called.

end of main.Press any key to continue . . .

Unwinding of the stack caused by an exception

In unwinding the stack, the program does not destroy static variables, static objects, or global variables.

They will be destroyed when the program exits.

Dynamic objects created with the new operator new operator will have to be explicitly destroyed using deletedelete.

Usually, they are deleted within the catch block.

Exhandling.cpp

Page 22: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

22

Notice that as soon as any exception is thrownthrown, no further statements are executed within the trytry block.

After the codes in the triggered catchcatch clause is executed, control passes immediately to the statement following the last catch block and the program finishes normally.

Unwinding of the stack caused by an Unwinding of the stack caused by an exceptionexception

Page 23: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

23

If an exceptionexception occurs while the catch parameter is being initialised or during the unwinding of the stack, the exception mechanism immediately calls the terminate()terminate() function without attempting to find another exception handler.

Unwinding of the stack caused by an Unwinding of the stack caused by an exceptionexception

When the terminate_handler terminate_handler is called because no matching exception handler was found, it is implementation-definedimplementation-defined whether the stack is unwound and local objects are destroyed.

(Technical Report on C++ Performance)

Page 24: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

24

Exception handling Exception handling provides a systematic and robust approach to coping with errorserrors that cannot be recovered from locally at the point where they are detected.

Page 25: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

25

#include <iostream>#include <exception>#include <fstream>using namespace std;

namespace MyLibrary {

int OPENFAILUREOPENFAILURE = 1;int OUTOFMEMORYOUTOFMEMORY = 2;int CORRUPTFILECORRUPTFILE = 3;//enum {OPENFAILURE=1,// OUTOFMEMORY = 2,CORRUPTFILE = 3};char * EmptyFile = "****Warning Empty File****";

char* readHeaderreadHeader( char * filename )throwthrow (int, char*) { char *temp; ifstream ifs( filename );

if ( !ifs )throwthrow OPENFAILUREOPENFAILURE;

const int bufferSize = 1024; temp = new char[bufferSize]; if( temp == NULL ) throwthrow OUTOFMEMORYOUTOFMEMORY;

ifs.getline( temp, bufferSize );

if ( ifs.bad() ){ ifs.close(); delete [] temp; throwthrow CORRUPTFILECORRUPTFILE; } if( temp[0] == '\0' ) { ifs.close(); delete [] temp; throwthrow EmptyFile; }

return temp;}}; // end of namespace definition

using namespace MyLibrary;

int main(){ char filename[80]; cout << "Enter a filename: "; cin.getline( filename, sizeof(filename) ); char *header; trytry { header = readHeaderreadHeader( filename );( filename ); } catchcatch( int ex ) { cout << "Caught exception code " << ex << endl; exit(1); // could decide here to ask again if file name was

wrong } catchcatch( char * ex ) { cout << "Caught exception message " << ex << endl; exit(1); } cout << "Header is:" << header << endl; delete [] header; return 0;}

Example output (program run 3 separate times):Enter a filename: readme.txtHeader is: hello there!

Enter a filename: emptyfile.txtCaught exception message Caught exception message ****Warning Empty File****

Enter a filename: non-existentfile.txtCaught exception code Caught exception code 1

Page 26: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

26

const int OPENFAILURE = 1;const int OUTOFMEMORY = 2;const int CORRUPTFILE = 3;

//enum {OPENFAILURE=1,OUTOFMEMORY = 2,CORRUPTFILE = 3};

Use const int or int variables for the exception-specification but not enum; Otherwise, the program will fail to handle the exceptions (in gcc).

Data type issuesData type issues

Page 27: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

File Handling

• Let’s look at a more complete program for opening a file with exception handling.

• File Exception Handling 5.cpp

27

Page 28: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

28

• Not every C++ program should use exception handling.

• Throwing exceptions is slower is slower than function calls.

• Use other error handling techniques

( such as returning an error code) when appropriate.

• Exception handling is used to communicate program to communicate program anomaliesanomalies between parts of a program that are developed independently (e.g. librarieslibraries).

• It does allow the user of the library to decide what to do when an error occurs rather than hard coding the decisions into the library.

Design ConsiderationsDesign Considerations

Page 29: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

29

An ExceptionException is an interruption in the normal flow of program control in response to an unexpected or abnormal event.

Normally, these conditions terminate the user program with system-provided error message.

Exception handling Exception handling provides a systematic and robust approach to coping with errors that cannot be recovered from locally at the point where they are detected.

C++ code can raise an exception by using the throwthrow expression.

The exception is handled by invoking an appropriate handler (catch clausecatch clause) selected from a list of handlers found at the end of the handler’s try block.

SummarySummary

Page 30: 1 159.234LECTURE 14 159.234 LECTURE 14 Exception Handling Textbook p. 309-321

Additional References

30

Technical Report on C++ Performance ISO/IEC TR 18015:2006(E)

Next: Inheritance

Mastering Visual C++

http://www.cplusplus.com/reference/iostream/ios/bad.html