Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab."— Presentation transcript:

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

2 SNU OOPSLA Lab. C++ 2 Contents Error Handling Grouping of Exceptions Catching Exceptions Resource Management Exceptions That Are Not Errors Exception Specifications Uncaught Exceptions Standard Exceptions

3 SNU OOPSLA Lab. C++ 3 1. Error Handling(1) Author of a library User of a library Can detect run-time errors but does not in general have any idea what to do about them Problem occurs May know how to cope with such errors but cannot detect them Notion of Exception

4 SNU OOPSLA Lab. C++ 4 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”

5 SNU OOPSLA Lab. C++ 5 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)

6 SNU OOPSLA Lab. C++ 6 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

7 SNU OOPSLA Lab. C++ 7 Structure of exception handling class exception_type {... }; try { throw exception_object ; // throw exception } catch ( exception_type ) { // exception handler //... } Structure of exception handling

8 SNU OOPSLA Lab. C++ 8 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)

9 SNU OOPSLA Lab. C++ 9 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 }

10 SNU OOPSLA Lab. C++ 10 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 Without grouping void g() { try { // … } catch (Overflow) { /* … */ } catch (Underflow) { /* … */ } catch(Zerodivide) { /* … */ } }

11 SNU OOPSLA Lab. C++ 11 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 class class 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)

12 SNU OOPSLA Lab. C++ 12 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

13 SNU OOPSLA Lab. C++ 13 2.2 Composite Exceptions Not every grouping of exceptions is a tree structure Often, an exception belongs to two groups class 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

14 SNU OOPSLA Lab. C++ 14 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? }

15 SNU OOPSLA Lab. C++ 15 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)

16 SNU OOPSLA Lab. C++ 16 3.1 Re-Throw The handler typically does what can be done locally and then throws the exception again void 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 here throw;// re-throw the exception } without operand

17 SNU OOPSLA Lab. C++ 17 3.2 Catch Every Exception Catch any exception  catch(…) void m() { try { // something } catch(...) {//handle every exception // cleanup throw; }

18 SNU OOPSLA Lab. C++ 18 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 }  

19 SNU OOPSLA Lab. C++ 19 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

20 SNU OOPSLA Lab. C++ 20 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

21 SNU OOPSLA Lab. C++ 21 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

22 SNU OOPSLA Lab. C++ 22 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 p; void init(); public: Z(int s) : p(s) { init(); } // … }; The memory used by p is managed by vector

23 SNU OOPSLA Lab. C++ 23 4.2 Auto_ptr(1) The standard library provides the template class auto_ptr Supports the “resource acquisition is initialization” technique class Mess { }; void f(Point p1, Point p2) { auto_ptr p(new Rectangle(p1, p2)); // p points to the rectangle p->retate(45); // … if (in_a_mess) throw Mess(); // … } Rectangle is deleted whether or not an exception is thrown

24 SNU OOPSLA Lab. C++ 24 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 p; // … public: X() { p = new Y(2); /* … */ }; // … };

25 SNU OOPSLA Lab. C++ 25 template class std::auto_ptr { public: typedef X element_type; explicit auto_ptr(X* =0) throw(); auto_ptr(const auto_ptr&) throw(); template &) throw(); auto_ptr& operator=(const auto_ptr&) throw(); template auto_ptr& operator=(const auto_ptr &) throw(); ~auto_ptr(); X& operator*() const throw(); X* operaotr->() const throw(); X* relaease() const throw();// relinquish ownership X* get() const throw();//get ownership back // … implementation details … }; standard header

26 SNU OOPSLA Lab. C++ 26 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 p2(p);// now p2 is responsible for deletion auto_ptr p3(p2);// now p3 is responsible for deletion (and p2 isn’t) auto_ptr p4(p);// programming error: // now p4 is also responsible for deletion // … }

27 SNU OOPSLA Lab. C++ 27 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(…)

28 SNU OOPSLA Lab. C++ 28 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]; }

29 SNU OOPSLA Lab. C++ 29 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

30 SNU OOPSLA Lab. C++ 30 4.5 Resource Exhaustion(2) void* operator new(size_t size) { for (;;) { if (void* p = malloc(size)) return p;// try to find memory if (_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

31 SNU OOPSLA Lab. C++ 31 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

32 SNU OOPSLA Lab. C++ 32 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 }

33 SNU OOPSLA Lab. C++ 33 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

34 SNU OOPSLA Lab. C++ 34 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 // … }

35 SNU OOPSLA Lab. C++ 35 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 itself X::~X() try { f();// might throw } catch (…) { // do something }

36 SNU OOPSLA Lab. C++ 36 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

37 SNU OOPSLA Lab. C++ 37 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

38 SNU OOPSLA Lab. C++ 38 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 anything virtual void g() throw (X, Y); virtual void h() throw (X); }; class D : public B { public: void f() throw (X);//ok void g() throw (X);//ok void h() throw (X, Y); }; error: D::h() is less restrictive than B::h()

39 SNU OOPSLA Lab. C++ 39 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

40 SNU OOPSLA Lab. C++ 40 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

41 SNU OOPSLA Lab. C++ 41 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);

42 10. Standard Exceptions(1) Standard Exceptions (thrown by language) NameThrown byReference bad_allocnew§6.2.6.2, §19.4.5 bad_castdynamic_cast§15.4.1.1 bad_typeidtypeid§15.4.4 bad_exceptionexception 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.1 overflow_error bitset<>::to_ulong()§17.5.3.3 ios_base::failure ios_base::clear§21.3.6

43 SNU OOPSLA Lab. C++ 43 10. Standard Exceptions(2) exception logic_errorruntime_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


Download ppt "SNU OOPSLA Lab. 14. Exception Handling © copyright 2001 SNU OOPSLA Lab."

Similar presentations


Ads by Google