SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

43
SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

Transcript of SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

Page 1: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

SNUOOPSLA Lab.

14. Exception Handling

© copyright 2001 SNU OOPSLA Lab.

Page 2: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

2SNUOOPSLA Lab.C++

Contents

Error Handling Grouping of Exceptions Catching Exceptions Resource Management Exceptions That Are Not Errors Exception Specifications Uncaught Exceptions Standard Exceptions

Page 3: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

3SNUOOPSLA Lab.C++

1. Error Handling(1)

Author of a library User of a library

Can detect run-time errorsbut does not in general have any idea what to do about them

Problemoccurs

May know how to cope with such errors but cannot detect them

Notion of Exception

Page 4: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

4SNUOOPSLA Lab.C++

1. Error Handling(2)

Traditional techniques terminate the program return a value representing “error” return a legal value and leave the program in an

illegal state call a function supplied to be called in case of “error”

Page 5: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

5SNUOOPSLA Lab.C++

Exception handling separates error handling code from “ordinary code”, so program is

more readable more amenable

In exception handling, default response to an error is to terminate the program, so

design process is more important the work involved in getting a program running is

harder

1. Error Handling(3)

Page 6: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

6SNUOOPSLA Lab.C++

Alternative views on exceptions to support error handling to handle only synchronous exceptions

ex) array range checks and I/O errors

a non-local control structure based on stack

C++ exception handling mechanisms are provided to report and handle errors and exceptional events

1.1 Alternative views on exceptions

Page 7: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

7SNUOOPSLA Lab.C++

Structure of exception handling

class exception_type { ... };

try {

throw exception_object ;

// throw exception

}

catch ( exception_type <name> ) {

// exception handler

// ...

}

Structure of exception handling

Page 8: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

8SNUOOPSLA Lab.C++

An exception is an object of some class representing an exceptional occurrence

Code that detects an error throws an object A piece of code express desire to handle an

exception by a catch clause The effect of throw is to unwind the stack until

catch is found Exceptions fall into families

2. Grouping of Exceptions (1)

Page 9: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

9SNUOOPSLA Lab.C++

2. Grouping of Exceptions (2)

Exception for a mathematical library

Handle any Matherr without caring precisely which kind it is

class Matherr { };class Overflow : public Matherr{ };class Underflow : public Matherr{ };class Zerodivide : public Matherr{ };

try { // ...}catch (Overflow) {

// handle Overflow or anything derived from Overflow} catch (Matherr) {

// handle any Matherr that is not Overflow}

Page 10: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

10SNUOOPSLA Lab.C++

Organizing into hierarchies can be important for robustness of code

If not, be done by exhaustively listing the exceptions

2. Grouping of Exceptions (3)

Matherr

Underflow

ZerodivideOverflow

Withoutgrouping

void g(){

try {// …

}catch (Overflow) { /* … */ }catch (Underflow) { /* … */ }catch(Zerodivide) { /* … */ }}

Page 11: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

11SNUOOPSLA Lab.C++

2.1 Derived Exceptions(1) An exception is typically caught by a handler

for its base class rather than by a handler for its exact classclass Matherr {// …virtual void debug_ptint() const { … }

};

class Int _overflow : public Matherr {const char* op;int a1, a2;

public:Int_overflow(const char *p, int a, int b) { … }

virtual void debug_print() const { … }// …

};

void f(){

try {g();

}catch (Matherr m) {

// …}

}

If g() throw Int_overflow? M is Matherr object(Problem)

Page 12: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

12SNUOOPSLA Lab.C++

2.1 Derived Exceptions(2)Int add(int s, int y){

if ((x>0 && y>0 && x>INT_MAX-y) || x<0 && y<0 && x<INT_MIN-y))throw Int_overflow(“+”,x,y);

return x+y;}

void f(){

try {int i1 = add(1, 2);int i2 = add(INT_MAX, 2);

}catch (Matherr& m) {

m.debug_print();}

}

Int_overflow::debug_print() will be invoked

Page 13: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

13SNUOOPSLA Lab.C++

2.2 Composite Exceptions Not every grouping of exceptions is a tree

structure Often, an exception belongs to two groupsclass Netfile_err : public Network_err, public File_system_err { …};

void f(){

try {// something

catch (Network_err& e) {// …

}}

void g(){

try {// something else

}catch (File_system_err& e) {

// …}

}Network exception

File system exception

Page 14: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

14SNUOOPSLA Lab.C++

3. Catching Exceptions(1)

The handler is invoked: if H is the same type as E if H is an unambiguous public base of E if H and E are pointer types and or holds for the

types to which they refer if H is a reference and or holds for the type to

which H refers

void f(){

try {throw E();

}catch(H) {

// when do we get here?}

}

Page 15: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

15SNUOOPSLA Lab.C++

An exception is copied when it is thrown, so the handler gets hold of a copy of the original exception

An exception may be copied several times before it is caught

Cannot throw an exception that cannot be copied

3. Catching Exceptions(2)

Page 16: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

16SNUOOPSLA Lab.C++

3.1 Re-Throw The handler typically does what can be done

locally and then throws the exception againvoid h(){

try {// code that might throw Math errors

}catch (Matherr) {

if (can_handle_it_completely) {// handle the Matherr

return;}else {

// do what can be done herethrow; // re-throw the exception

}}

} without operand

Page 17: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

17SNUOOPSLA Lab.C++

3.2 Catch Every Exception Catch any exception catch(…)

void m(){

try {// something

}catch(...) { //handle every exception

// cleanupthrow;

}}

Page 18: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

18SNUOOPSLA Lab.C++

3.2.1 Order of handlers The handlers are tried in order

void f(){

try {// …

}catch (std::ios_base::failure) {

// handle any stream io error}catch (std::exception& e) {

// handle any standard library exception}catch (…) {

//handle any other exception}

}

Page 19: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

19SNUOOPSLA Lab.C++

4. Resource Management(1)

The function that acquired a resource release it before returning to its caller

void use_file (const char* fn){

FILE* f=open(fn, “r”);

// use f

fclose(f);}

void use_file (const char* fn){

FILE* f=open(fn, “r”);try {

// use f}

catch (…) {fclose(f);throw;

}fclose(f);}an exception may cause use_file()

to be exited without fcolse() being called

Ver. 1

Page 20: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

20SNUOOPSLA Lab.C++

Problem with Ver. 1 is that it is verbose, tedious, and potentially expensive

4. Resource Management(2)

void acquire(){

// acquire resource 1// …// acquire resource n

// use resources

// release resource n// …// release resource 1

}

General form of the problem(Ver. 1)

reverse order

Using constructors and destructors

class File_ptr {FILE* p;

public:File_ptr (const char* a)

{ p = fopen (n, a); }File_ptr (FILE* pp) { p = pp; }~File_ptr() { fclose(p); }

operator FILE* () { return p; }};

void use_file (const char* fn){

File_ptr f(fn, “r”);// use f

}

Ver. 2

Page 21: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

21SNUOOPSLA Lab.C++

4.1 Using constructors and destructors(1)

“Resource acquisition is initialization” - the technique for managing resources using local objects

An object is not considered constructed until its constructor has completed

Page 22: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

22SNUOOPSLA Lab.C++

4.1 Using constructors and destructors(2)

Memory acquisition

class Y {int* p;void init();

public:Y(int s) { p = new int[s]; init(); }~Y() { delete []p; }// …

};

If an exception is thrown by init(), then the store acquired will not be freed

The destructor will not be called because the object wasn’t completely constructed

class Z {vector<int> p;

void init();public:

Z(int s) : p(s) { init(); }// …

};

The memory used by p is managed by vector

Page 23: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

23SNUOOPSLA Lab.C++

4.2 Auto_ptr(1) The standard library provides the template class auto

_ptr Supports the “resource acquisition is initialization” tec

hniqueclass Mess { };

void f(Point p1, Point p2){

auto_ptr<Rectangle> p(new Rectangle(p1, p2));// p points to the rectanglep->retate(45);// …if (in_a_mess) throw Mess();// …

}

Rectangle is deleted whether or not an exception is thrown

Page 24: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

24SNUOOPSLA Lab.C++

auto_ptr simplifies the task of writing classes with members that are pointers to objects that need to be deleted when the class objects is destroyed

4.2 Auto_ptr(2)

Class X {auto_ptr<Y> p;// …

public:X() { p = new Y(2); /* … */ };// …

};

Page 25: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

25SNUOOPSLA Lab.C++

template<class X> class std::auto_ptr {public:

typedef X element_type;

explicit auto_ptr(X* =0) throw();auto_ptr(const auto_ptr&) throw();template<class Y) auto_ptr(const auto_ptr<Y>&) throw();

auto_ptr& operator=(const auto_ptr&) throw();template<class Y> auto_ptr& operator=(const auto_ptr<Y>&) throw();

~auto_ptr();

X& operator*() const throw();X* operaotr->() const throw();

X* relaease() const throw(); // relinquish ownershipX* get() const throw(); //get ownership back

// … implementation details …};

<memory> standard header

Page 26: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

26SNUOOPSLA Lab.C++

After initial construction, an auto_ptr “owns” the object to which it holds a pointer; it is responsible for deleting it

The effect of having more than one auto_ptr “own” an object is undefined; most likely the object will be deleted twice

4.2 Auto_ptr(3)

void g(X* p){

auto_ptr<X>p2(p); // now p2 is responsible for deletionauto_ptr<X>p3(p2); // now p3 is responsible for deletion (and p2 isn’t)

auto_ptr<X>p4(p); // programming error:// now p4 is also responsible for deletion

// …}

Page 27: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

27SNUOOPSLA Lab.C++

4.3 Caveat Not all programs need to be resilient against all forms

of failure, and not all resources are critical enough to warrant the effort to protect then using “resource acquisition is initialization,” auto_ptr, and catch(…)

Page 28: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

28SNUOOPSLA Lab.C++

4.4.4 Exceptions and New

What happens if X’s constructor throws an exception?

Void f(Arena& a, X* buffer){

X* p1 = new X;X* p2 = new X[10];

X* p3 = new (buffer[10]) X; // place X in buffer (no deallocation needed)X* p4 = new (buffer[11]) X[10];

X* p5 = new(a) X; // allocation from Arena a (deallocate from a)X* p6 = new(a) X[10];

}

Page 29: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

29SNUOOPSLA Lab.C++

4.5 Resource Exhaustion(1) What to do when an attempt to acquire a

resource fails Two styles of solutions

resumption : ask some caller to fix the problem and carry on

termination : abandon the computation and return to some caller

In C++, resumption model : function-call mechanism termination model : exception handling model

Page 30: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

30SNUOOPSLA Lab.C++

4.5 Resource Exhaustion(2)

void* operator new(size_t size){

for (;;) {if (void* p = malloc(size)) return p; // try to find memoryif (_new_handler == 0) throw bad_alloc(); // no handler: give up_new_handler(); // ask for help

}}

void my_new_handler(){

int no_of_bytes_found = find_some_memory();if (no_of_bytes_found < min_allocation) throw bad_alloc(); //give up

Set_new_handler(&my_new_handler);

Pointer to a function maintained by the standard function set_new_handler

Page 31: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

31SNUOOPSLA Lab.C++

4.6 Exceptions in Constructors(2)

Exception handling allows the information that a construction failed to be transmitted out of the constructor

class Vector {public:

class Size { };

enum { max = 32000 };

Vector::Vector(int sz){

if (sz<0 || max<sz) throw Size();// ...

}// …

};

Protect itself from excessive demands on memory

Page 32: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

32SNUOOPSLA Lab.C++

4.6 Exceptions in Constructors(2)

Vector* f(int i){

try {Vector* p = new Vector(i);// …return p;

}catch (Vector::Size) {

// deal with size error}

}

Page 33: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

33SNUOOPSLA Lab.C++

4.6.1 Exceptions and Member Initialization(1)

What happens if a member initializer throws an exception?

By default, the exception is passed on to whatever invoked the constructor for the member’s class

The constructor itself can catch such exceptions by enclosing the complete function body in a try-block

Page 34: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

34SNUOOPSLA Lab.C++

4.6.1 Exceptions and Member Initialization(2)

class X {Vector v;// …

public:X(int);// …

};

X::X(int s)try

:v(s) // initialize v by s{

// …}catch (Vector::Rectagle) { // exceptions thrown for v are caught here

// …}

Page 35: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

35SNUOOPSLA Lab.C++

4.7 Exceptions in Destructors

A destructor can be called in one of two ways normal call : as the result of a normal exit from a

scope, a delete, etc. call during exception handling : during stack

unwinding, the exception-handling mechanism exits a scope containing an object with a destructor

If a destructor calls functions that may throw exceptions, it can protect itselfX::~X()

try {f(); // might throw

}catch (…) {

// do something}

Page 36: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

36SNUOOPSLA Lab.C++

6. Exception Specifications Specify the set of exceptions that might be

thrown as part of the function declaration

void f(int a) throw (x2, x3);

f() may throw only exceptions x2, x3, and exceptions derived from these types

void f() throw (x2, x3){

// stuff}

void f()try{

// stuff}catch (x2) { throw; }catch (x3) {throw; }catch (…) {

std::unexpected();}

=

The most important advantage is that the function declaration belongs to an interface that is visible to its callers

Page 37: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

37SNUOOPSLA Lab.C++

6.1 Checking Exception Specifications(1)

If any declaration of a function has an exception-specification, every declaration of that function must have an exception-specification with exactly the same set of exception types

int f() throw (std::bad_alloc);

int f(){

// …}

error : exception-specification missing

Page 38: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

38SNUOOPSLA Lab.C++

A virtual function may be overridden only by a function that has an exception-specification at least as restrictive as its own exception-specification

6.1 Checking Exception Specifications(2)

Class B {public:

virtual void f(); // can throw anythingvirtual void g() throw (X, Y);virtual void h() throw (X);

};

class D : public B {public:

void f() throw (X); //okvoid g() throw (X); //okvoid h() throw (X, Y);

};

error: D::h() is less restrictive than B::h()

Page 39: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

39SNUOOPSLA Lab.C++

6.2 Unexpected Exceptions An exception-specification can lead to calls to

unexpected() Such calls can be avoided through careful

organization of exceptions and specification of interfaces

Calls to unexpected() can be intercepted and rendered harmless

Page 40: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

40SNUOOPSLA Lab.C++

6.3 Mapping Exceptions The policy of terminating a program upon encountering

an unexpected exception is too Draconian The behavior of unexpected() must be modified Add the standard library exception std::bad_exception

to an exception-specification

Class X{ };class Y{ };

void f() throw (X, std::bad_exception){

// …throw Y();

}

The exception-specification will catch the unacceptable exception Y and throw an exception of type bad_exception instead

Page 41: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

41SNUOOPSLA Lab.C++

7.Uncaught Exceptions If an exception is thrown but not caught, the

function std::terminate() will be called The response to an uncaught exception is

determined by an _uncaught_handler set by set_terminate()

Typedef void(*PFV)();PFV set_terminate(PFV);

Page 42: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

10. Standard Exceptions(1)

Standard Exceptions (thrown by language)

Name Thrown by Reference

bad_alloc new §6.2.6.2, §19.4.5bad_cast dynamic_cast §15.4.1.1bad_typeid typeid §15.4.4bad_exception exception specification §14.6.3

Standard Exceptions (thrown by standard library)

out_of_range at() §3.7.2, §16.3.3, §20.3.3 bitset<>::operator[]() §17.5.3

invalid_argument bitset constructor §17.5.3.1overflow_error bitset<>::to_ulong() §17.5.3.3ios_base::failure ios_base::clear §21.3.6

Page 43: SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab.

43SNUOOPSLA Lab.C++

10. Standard Exceptions(2)

exception

logic_error runtime_error

length_error

domain_error

out_of_range

invalid_argument

bad_alloc

bad_exception

ios_base::failure

bad_cast

range_error

overflow_error

underflow_errorbad_typeid