Oct 11, 2007 Handling Exceptions in C++ Dr. Partha Pratim Das Interra Systems (India) Pvt. Ltd.   PART B
Agenda <ul><li>PART A </li></ul><ul><ul><li>Exception Fundamentals </li></ul></ul><ul><ul><li>Exceptions in C </li></ul></...
Agenda <ul><li>PART B </li></ul><ul><ul><li>Exception Instrumentations in C++ </li></ul></ul><ul><ul><ul><li>How Compilers...
Agenda <ul><li>PART C </li></ul><ul><ul><li>Designing with Exceptions in C++  </li></ul></ul><ul><ul><ul><li>Analysis & De...
PART B
Exceptions Instrumentations in C++ How compilers manage Exceptional Flow
Exception Handling : Issues <ul><li>Code Isolation </li></ul><ul><ul><li>Separate Exceptions Flow from Normal Flow </li></...
Function Call : Instrumentations <ul><li>Normal Flow </li></ul><ul><ul><li>return  </li></ul></ul><ul><li>Exceptional Flow...
Function Call : Items <ul><li>Normal Call </li></ul><ul><ul><li>Stack Frame </li></ul></ul><ul><ul><li>Context </li></ul><...
Function Call Items : Stack Frame <ul><li>Function parameters  </li></ul><ul><li>Function return address  </li></ul><ul><l...
Function Call Items : Context <ul><li>Register PC / Return Address  </li></ul><ul><ul><li>(eip on x86) </li></ul></ul><ul>...
Function Call Items : Finalization <ul><li>How are the right destructors called in the right order?  </li></ul><ul><ul><li...
Function Call : Normal Flow <ul><li>Caller prepares the Parameters </li></ul><ul><li>Caller calls the Callee </li></ul><ul...
Function Call Items : Stack Frame
Function Call Items : EH Frame
Function Call : Stack Cutting <ul><li>setjmp sets the jmp_buf buffer. </li></ul>#define _JBLEN  16 #define _JBTYPE int // ...
Function Call : Stack Cutting <ul><li>longjmp forces the context (FP, SP and PC) to the jmp_buf buffer stored at setjmp po...
Function Call Items : Stack Frame
Function Call Items : Thunk <ul><li>A delayed computation </li></ul><ul><li>Runtime registers a destructor thunk for the e...
Function Call Items : EH Handler
Function Call : Stack Unwinding <ul><li>Flow: </li></ul><ul><ul><li>Creation of Exception object </li></ul></ul><ul><ul><l...
Function Call : Stack Unwinding <ul><li>Flow: </li></ul><ul><ul><li>Invocation of the right handler. </li></ul></ul><ul><u...
Function Call : Stack Unwinding <ul><li>Data Structures: </li></ul><ul><ul><li>Stack Frame </li></ul></ul><ul><ul><li>RUNT...
Exception Handling : Trade Off
Designing with Exceptions in C++ Glimpses of Design Issues
Designing with Exceptions : Goals <ul><li>“ With Exceptions” !!! </li></ul><ul><ul><li>Designing  in spite of  Exceptions?...
Designing with Exceptions : Goals <ul><li>Graded Goals </li></ul><ul><ul><li>Do Nothing </li></ul></ul><ul><ul><li>No Cras...
Exception Safety : Levels <ul><li>No Exception Safety </li></ul><ul><ul><li>No guarantees are made.  </li></ul></ul><ul><u...
Exception Safety : Levels <ul><li>Strong Exception Guarantee (Commit or Rollback)  </li></ul><ul><ul><li>Failed operations...
Designing with Exceptions : Scope <ul><li>We Consider: </li></ul><ul><ul><li>Function Calls </li></ul></ul><ul><ul><ul><li...
Designing with Exceptions : Scope <ul><li>We do not consider: </li></ul><ul><ul><li>Static Objects </li></ul></ul><ul><ul>...
C++ Ground Rules : Lifetime <ul><li>When does an object's lifetime begin? </li></ul><ul><ul><li>When its constructor compl...
C++ Ground Rules : Lifetime <ul><li>Construction: </li></ul><ul><ul><li>An object is considered  fully constructed  when t...
Anatomy of a Function <ul><li>Safe Operations </li></ul><ul><ul><li>Operations with built-in types </li></ul></ul><ul><ul>...
Exceptional Design Rules Meyers’ Recommendations on Basic Exception Safety
Exception Safety :  Meyers Guidelines <ul><li>Item 9:  Use destructors to prevent resource leaks   </li></ul><ul><li>Item ...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Situation   </li></ul><ul><ul><li>A hierarchy of Polygonal...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Classes </li></ul>class Poly { public:  virtual void plotP...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>plot() for the Graphic Device (unsafe) </li></ul><ul><li>v...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>plot() for the Graphic Device (safe) </li></ul><ul><li>voi...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Litter code with try and catch blocks.  </li></ul><ul><li>...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Smart pointer  </li></ul><ul><ul><li>Is a C++ object  </li...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>auto_ptr </li></ul><ul><li>template<class T>  </li></ul><u...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>plot() for the Graphic Device (safe) </li></ul><ul><li>voi...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Smart Pointers work as Holders of Resources </li></ul><ul>...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Window Handling in Windows OS (unsafe) </li></ul><ul><li>/...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Window Holder </li></ul><ul><li>// class for Holding (acqu...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Window Handling in Windows OS (safe) </li></ul><ul><li>// ...
Meyers [9] :  Use destructors to prevent resource leaks <ul><li>Morale </li></ul><ul><ul><li>Resources should be encapsula...
More Questions   <ul><li>What happens if an exception is thrown in the process of acquiring a resource, that is, in the  c...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Consider:  </li></ul><ul><li>class T { ... };  </li></ul><...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Constructor (unsafe) / Destructor:  </li></ul><ul><li>A::A...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Exception in body: </li></ul><ul><ul><li>operator (T)  may...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Try Exception Fix by Dynamic Allocation </li></ul><ul><ul>...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Constructor (safe) cleans up itself </li></ul><ul><li>A::A...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Constructor (safe): w/o code duplication </li></ul><ul><li...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Reconsider:  </li></ul><ul><li>class T { ... };  </li></ul...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Constructor (unsafe):  </li></ul><ul><li>Exception at Line...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Constructor (safe):  </li></ul><ul><li>T1* A::InitT1(const...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>A better design:  </li></ul><ul><li>class T { ... };  </li...
Meyers [10] :  Prevent resource leaks in constructors   <ul><li>Constructor (safe by design):  </li></ul><ul><li>Exception...
Meyers [10] :  Prevent resource leaks in constructors <ul><li>Moral </li></ul><ul><ul><li>Replace pointer class members wi...
Meyers [11] :  Prevent exceptions from leaving destructors   <ul><li>A destructor is called in two situations  </li></ul><...
Meyers [11] :  Prevent exceptions from leaving destructors   <ul><li>Recap  </li></ul><ul><ul><li>If an exception is throw...
Meyers [11] :  Prevent exceptions from leaving destructors   <ul><li>Consider  </li></ul><ul><li>class Session {  </li></u...
Meyers [11] :  Prevent exceptions from leaving destructors   <ul><li>Manage the exceptions  </li></ul><ul><li>Session::~Se...
Meyers [11] :  Prevent exceptions from leaving destructors   <ul><li>Bite the dust – swallow the exceptions  </li></ul><ul...
Meyers [11] :  Prevent exceptions from leaving destructors   <ul><li>Moral  </li></ul><ul><ul><li>Keep exceptions from pro...
Meyers [12] :  Throwing an exception differs from passing a parameter or calling a virtual function  <ul><li>Control does ...
Meyers [13] :  Catch exceptions by reference
Meyers [14] :    Use exception specifications judiciously
Meyers [15] :    Understand the costs of exception handling
Handling Exceptions in  C & C++ References & Credits
References <ul><li>Handling Exceptions: Part 1 – 4 </li></ul><ul><ul><li>Robert Schmidt </li></ul></ul><ul><li>Modern C++ ...
Credits / Acknowledgements
Thank You
Upcoming SlideShare
Loading in …5
×

Handling Exceptions In C &amp; C++ [Part B] Ver 2

1,512 views

Published on

Second part of my series on Exception Handling. Talks mostly of the stuff in C++. Prepared in 2007

  • Be the first to comment

  • Be the first to like this

Handling Exceptions In C &amp; C++ [Part B] Ver 2

  1. 1. Oct 11, 2007 Handling Exceptions in C++ Dr. Partha Pratim Das Interra Systems (India) Pvt. Ltd. PART B
  2. 2. Agenda <ul><li>PART A </li></ul><ul><ul><li>Exception Fundamentals </li></ul></ul><ul><ul><li>Exceptions in C </li></ul></ul><ul><ul><ul><li>C Language Features </li></ul></ul></ul><ul><ul><ul><li>C Standard Library Support </li></ul></ul></ul><ul><ul><li>SEH in Microsoft C </li></ul></ul><ul><ul><li>Exceptions in C++ </li></ul></ul><ul><ul><ul><li>C++ Language Features </li></ul></ul></ul><ul><ul><ul><ul><li>try–catch–throw </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Exception Specifications </li></ul></ul></ul></ul><ul><ul><ul><li>C++ Standard Library Support </li></ul></ul></ul>
  3. 3. Agenda <ul><li>PART B </li></ul><ul><ul><li>Exception Instrumentations in C++ </li></ul></ul><ul><ul><ul><li>How Compilers Manage Exceptional Flow? </li></ul></ul></ul><ul><ul><li>Designing with Exceptions in C++ </li></ul></ul><ul><ul><ul><li>Goals </li></ul></ul></ul><ul><ul><ul><li>Scope </li></ul></ul></ul><ul><ul><ul><li>Anatomy of a Function </li></ul></ul></ul><ul><ul><ul><li>Meyers Guidelines </li></ul></ul></ul>
  4. 4. Agenda <ul><li>PART C </li></ul><ul><ul><li>Designing with Exceptions in C++ </li></ul></ul><ul><ul><ul><li>Analysis & Design of an Exception-safe stack </li></ul></ul></ul><ul><ul><ul><li>Exception behavior of Standard Library </li></ul></ul></ul><ul><ul><ul><li>Handling Exceptions in Multithreaded Environment </li></ul></ul></ul><ul><ul><ul><li>TR1 Proposal </li></ul></ul></ul>
  5. 5. PART B
  6. 6. Exceptions Instrumentations in C++ How compilers manage Exceptional Flow
  7. 7. Exception Handling : Issues <ul><li>Code Isolation </li></ul><ul><ul><li>Separate Exceptions Flow from Normal Flow </li></ul></ul><ul><ul><li>Separate Error Reporting from Error Handling </li></ul></ul><ul><li>Efficiency </li></ul><ul><ul><li>Minimal Time Overhead for Normal Flow </li></ul></ul><ul><ul><li>Minimal Space Overhead for Normal Flow </li></ul></ul><ul><li>Optimization </li></ul><ul><ul><li>Minimize Loss of code optimizations under Exceptions </li></ul></ul><ul><li>Safety </li></ul><ul><ul><li>Contain the vulnerability of the Program </li></ul></ul>
  8. 8. Function Call : Instrumentations <ul><li>Normal Flow </li></ul><ul><ul><li>return </li></ul></ul><ul><li>Exceptional Flow with Stack Cutting </li></ul><ul><ul><li>setjmp / longjmp </li></ul></ul><ul><li>Exceptional Flow with Stack Unwinding </li></ul><ul><ul><li>try-catch-throw </li></ul></ul>
  9. 9. Function Call : Items <ul><li>Normal Call </li></ul><ul><ul><li>Stack Frame </li></ul></ul><ul><ul><li>Context </li></ul></ul><ul><ul><li>Finalization </li></ul></ul><ul><li>Stack Cutting </li></ul><ul><ul><li>Enhanced Stack Frame </li></ul></ul><ul><ul><li>Exception Handler Frame </li></ul></ul><ul><li>Stack Unwinding </li></ul><ul><ul><li>Destructor Thunk </li></ul></ul><ul><ul><li>EH Handler </li></ul></ul>
  10. 10. Function Call Items : Stack Frame <ul><li>Function parameters </li></ul><ul><li>Function return address </li></ul><ul><li>Frame pointer </li></ul><ul><li>Local Objects </li></ul><ul><li>Callee save registers </li></ul>
  11. 11. Function Call Items : Context <ul><li>Register PC / Return Address </li></ul><ul><ul><li>(eip on x86) </li></ul></ul><ul><li>Register SP / Stack Pointer </li></ul><ul><ul><li>(esp on x86) </li></ul></ul><ul><li>Register FP / Frame Pointer or Base Pointer </li></ul><ul><ul><li>(ebp on x86) </li></ul></ul>
  12. 12. Function Call Items : Finalization <ul><li>How are the right destructors called in the right order? </li></ul><ul><ul><li>On Normal Exit </li></ul></ul><ul><ul><li>On Exceptional Exit </li></ul></ul><ul><li>NOTE: </li></ul><ul><ul><li>This is tricky once the function has a multiple return statements before / after a number of local object constructions </li></ul></ul>
  13. 13. Function Call : Normal Flow <ul><li>Caller prepares the Parameters </li></ul><ul><li>Caller calls the Callee </li></ul><ul><li>Callee saves the Context (Function Prologue) </li></ul><ul><li>Callee does the job </li></ul><ul><li>Callee restores the Context (Function Epilogue) </li></ul><ul><li>Callee returns </li></ul><ul><li>Caller cleans up the Parameters </li></ul><ul><li>Caller uses the return value </li></ul>
  14. 14. Function Call Items : Stack Frame
  15. 15. Function Call Items : EH Frame
  16. 16. Function Call : Stack Cutting <ul><li>setjmp sets the jmp_buf buffer. </li></ul>#define _JBLEN  16 #define _JBTYPE int // Define jump buffer layout for x86 setjmp/longjmp. typedef struct __JUMP_BUFFER {      unsigned long Ebp;     unsigned long Ebx;     unsigned long Edi;     unsigned long Esi;     unsigned long Esp;     unsigned long Eip;     unsigned long Registration;     unsigned long TryLevel;     unsigned long Cookie;     unsigned long UnwindFunc;     unsigned long UnwindData[6]; } _JUMP_BUFFER; typedef _JBTYPE jmp_buf[_JBLEN];
  17. 17. Function Call : Stack Cutting <ul><li>longjmp forces the context (FP, SP and PC) to the jmp_buf buffer stored at setjmp point. </li></ul><ul><li>Effect is – control resurfaces in setjmp and longjmp never returns. </li></ul><ul><li>Stack is ‘CUT’: </li></ul><ul><ul><li>Local objects are not finalized </li></ul></ul><ul><ul><li>All intervening frames are trashed </li></ul></ul>
  18. 18. Function Call Items : Stack Frame
  19. 19. Function Call Items : Thunk <ul><li>A delayed computation </li></ul><ul><li>Runtime registers a destructor thunk for the exception object. </li></ul><ul><li>Catch handler calls the thunk at end. </li></ul>
  20. 20. Function Call Items : EH Handler
  21. 21. Function Call : Stack Unwinding <ul><li>Flow: </li></ul><ul><ul><li>Creation of Exception object </li></ul></ul><ul><ul><li>Placement of destructor thunk for Exception object </li></ul></ul><ul><ul><li>Wrapping up of the stack frame. </li></ul></ul><ul><ul><li>Calling of Finalizers – ‘UNWIND’ </li></ul></ul><ul><ul><li>Matching for Handler </li></ul></ul><ul><ul><ul><li>Catch handlers are statically overloaded but dynamically dispatched. </li></ul></ul></ul><ul><ul><ul><li>Explain why this will need RTTI. </li></ul></ul></ul>
  22. 22. Function Call : Stack Unwinding <ul><li>Flow: </li></ul><ul><ul><li>Invocation of the right handler. </li></ul></ul><ul><ul><li>Exit from the handler </li></ul></ul><ul><ul><li>Invocation of the thunk if no rethrow has been done. </li></ul></ul>
  23. 23. Function Call : Stack Unwinding <ul><li>Data Structures: </li></ul><ul><ul><li>Stack Frame </li></ul></ul><ul><ul><li>RUNTIME_FUNCTION </li></ul></ul><ul><ul><li>UNWIND_INFO </li></ul></ul><ul><ul><li>TRY_REGION_TABLE </li></ul></ul><ul><ul><li>CLEANUP_TABLE </li></ul></ul>
  24. 24. Exception Handling : Trade Off
  25. 25. Designing with Exceptions in C++ Glimpses of Design Issues
  26. 26. Designing with Exceptions : Goals <ul><li>“ With Exceptions” !!! </li></ul><ul><ul><li>Designing in spite of Exceptions? </li></ul></ul><ul><ul><li>Designing with the help of Exceptions? </li></ul></ul><ul><ul><li>Both. </li></ul></ul>
  27. 27. Designing with Exceptions : Goals <ul><li>Graded Goals </li></ul><ul><ul><li>Do Nothing </li></ul></ul><ul><ul><li>No Crash </li></ul></ul><ul><ul><li>No Resource Leak </li></ul></ul><ul><ul><li>Valid System State </li></ul></ul><ul><ul><li>Unchanged System State </li></ul></ul><ul><ul><li>Works ALWAYS </li></ul></ul>No Safety Minimal Safety Basic Safety Strong Safety No-Throw Safety
  28. 28. Exception Safety : Levels <ul><li>No Exception Safety </li></ul><ul><ul><li>No guarantees are made. </li></ul></ul><ul><ul><li>This is never acceptable in a production environment. </li></ul></ul><ul><li>Minimal Exception Safety </li></ul><ul><ul><li>Partial execution of failed operations may store invalid data but will not cause a crash. </li></ul></ul><ul><ul><li>This may be acceptable for a graceful exit. </li></ul></ul><ul><li>Basic Exception Guarantee </li></ul><ul><ul><li>Partial execution of failed operations can cause side effects </li></ul></ul><ul><ul><li>Invariants on the state are preserved </li></ul></ul><ul><ul><li>Any stored data will contain valid values. </li></ul></ul>
  29. 29. Exception Safety : Levels <ul><li>Strong Exception Guarantee (Commit or Rollback) </li></ul><ul><ul><li>Failed operations are guaranteed to have no side effects. </li></ul></ul><ul><ul><li>Operations either succeed or have no effect at all. </li></ul></ul><ul><li>No-Throw Guarantee (Failure Transparency) </li></ul><ul><ul><li>Operations are guaranteed to succeed and satisfy all requirements even in presence of exceptional situations. </li></ul></ul><ul><ul><li>Ideal; but may be unrealistic. </li></ul></ul><ul><ul><li>Usually not possible in libraries where complete knowledge of the application is not available. </li></ul></ul>
  30. 30. Designing with Exceptions : Scope <ul><li>We Consider: </li></ul><ul><ul><li>Function Calls </li></ul></ul><ul><ul><ul><li>Global Functions </li></ul></ul></ul><ul><ul><ul><li>Static Methods </li></ul></ul></ul><ul><ul><ul><li>Non-Static Methods </li></ul></ul></ul><ul><ul><ul><li>Virtual Functions </li></ul></ul></ul><ul><ul><ul><li>Operators (Overloaded) </li></ul></ul></ul><ul><ul><li>Objects </li></ul></ul><ul><ul><ul><li>Automatic </li></ul></ul></ul><ul><ul><ul><li>Dynamic </li></ul></ul></ul>
  31. 31. Designing with Exceptions : Scope <ul><li>We do not consider: </li></ul><ul><ul><li>Static Objects </li></ul></ul><ul><ul><li>Asynchronous Exceptions </li></ul></ul><ul><ul><li>Standard Library Objects </li></ul></ul><ul><ul><li>STL Containers </li></ul></ul><ul><ul><li>… </li></ul></ul>
  32. 32. C++ Ground Rules : Lifetime <ul><li>When does an object's lifetime begin? </li></ul><ul><ul><li>When its constructor completes successfully and returns normally. </li></ul></ul><ul><li>When does an object's lifetime end? </li></ul><ul><ul><li>When its destructor begins. </li></ul></ul><ul><li>What is the state of the object after its lifetime has ended? </li></ul><ul><ul><li>There is no object. </li></ul></ul>
  33. 33. C++ Ground Rules : Lifetime <ul><li>Construction: </li></ul><ul><ul><li>An object is considered fully constructed when the control goes out of constructor. </li></ul></ul><ul><li>Destruction: </li></ul><ul><ul><li>C++ refuses to call destructors for objects that haven't been fully constructed </li></ul></ul><ul><ul><li>When an object is destructed, all fully constructed sub-objects are destructed. </li></ul></ul><ul><li>Finalization: </li></ul><ul><ul><li>Destructors for all local objects are called on exit (except for abort(), exit() and longjmp()). </li></ul></ul>
  34. 34. Anatomy of a Function <ul><li>Safe Operations </li></ul><ul><ul><li>Operations with built-in types </li></ul></ul><ul><ul><li>Compiler Mechanisms </li></ul></ul><ul><ul><ul><li>Call, Return, Try, Throw, Catch </li></ul></ul></ul><ul><ul><li>Safe Functions </li></ul></ul><ul><li>Unsafe Operations </li></ul><ul><ul><li>Functions </li></ul></ul><ul><ul><li>Construction </li></ul></ul><ul><ul><li>Copy Construction </li></ul></ul><ul><ul><li>Copy Assignment </li></ul></ul><ul><ul><li>Destruction </li></ul></ul><ul><ul><li>operator new / delete </li></ul></ul><ul><ul><li>… </li></ul></ul><ul><li>class A { }; </li></ul><ul><li>A Viscera( </li></ul><ul><ul><li>A x , // Argument Copy </li></ul></ul><ul><ul><li>A& rx , </li></ul></ul><ul><ul><li>A* px ) </li></ul></ul><ul><li>{ // Local objects </li></ul><ul><ul><li>A a ; </li></ul></ul><ul><ul><li>A& ra = *px ; </li></ul></ul><ul><ul><li>A* pa = new A(rx) ; </li></ul></ul><ul><ul><li>try { // ... </li></ul></ul><ul><ul><ul><li>// Parameter Copy </li></ul></ul></ul><ul><ul><ul><li>A a = // Return Value Copy </li></ul></ul></ul><ul><ul><ul><li>Viscera( a , *pa , &ra ); </li></ul></ul></ul><ul><ul><ul><li>// ... </li></ul></ul></ul><ul><ul><li>} catch ( A& e ) { </li></ul></ul><ul><ul><ul><li>// Handler </li></ul></ul></ul><ul><ul><li>} // Exception Destructor Thunk </li></ul></ul><ul><ul><li>// Exception Object Copy </li></ul></ul><ul><ul><li>throw x ; // Exception Exit </li></ul></ul><ul><ul><li>// Temporary Object Copy </li></ul></ul><ul><ul><li>return a ; // Normal Exit </li></ul></ul><ul><li>} // Local Object Cleanup </li></ul>
  35. 35. Exceptional Design Rules Meyers’ Recommendations on Basic Exception Safety
  36. 36. Exception Safety : Meyers Guidelines <ul><li>Item 9:  Use destructors to prevent resource leaks   </li></ul><ul><li>Item 10:  Prevent resource leaks in constructors   </li></ul><ul><li>Item 11:  Prevent exceptions from leaving destructors   </li></ul><ul><li>Item 12:  Understand how throwing an exception differs from passing a parameter or calling a virtual function   </li></ul><ul><li>Item 13:  Catch exceptions by reference   </li></ul><ul><li>Item 14:  Use exception specifications judiciously   </li></ul><ul><li>Item 15:  Understand the costs of exception handling   </li></ul>
  37. 37. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Situation </li></ul><ul><ul><li>A hierarchy of Polygonal objects </li></ul></ul><ul><ul><li>Two methods: </li></ul></ul><ul><ul><ul><li>Poly* readPoly(istream&) </li></ul></ul></ul><ul><ul><ul><ul><li>Read from input stream, and </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Create (through factory). </li></ul></ul></ul></ul><ul><ul><ul><li>virtual void plotPoly() </li></ul></ul></ul><ul><ul><ul><ul><li>Object drawn on the plotter device </li></ul></ul></ul></ul>Poly Quad Tri
  38. 38. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Classes </li></ul>class Poly { public: virtual void plotPoly() = 0; ... }; class Quad: public Poly { public: virtual void plotPoly(); ... }; class Tri: public Poly { public: virtual void plotPoly(); ... };
  39. 39. Meyers [9] : Use destructors to prevent resource leaks <ul><li>plot() for the Graphic Device (unsafe) </li></ul><ul><li>void plot(istream& myStream) { </li></ul><ul><ul><li>// while there's data </li></ul></ul><ul><ul><li>while (myStream) { </li></ul></ul><ul><ul><ul><li>// get next poly </li></ul></ul></ul><ul><ul><ul><li>Poly *pPoly = readPoly(myStream); </li></ul></ul></ul><ul><ul><ul><li>// Plot the polygon </li></ul></ul></ul><ul><ul><ul><li>pPoly->plotPoly(); </li></ul></ul></ul><ul><ul><ul><li>// delete object that </li></ul></ul></ul><ul><ul><ul><li>// readPoly returned </li></ul></ul></ul><ul><ul><ul><li>delete pPoly; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>plotPoly() throws  *pPoly leaks
  40. 40. Meyers [9] : Use destructors to prevent resource leaks <ul><li>plot() for the Graphic Device (safe) </li></ul><ul><li>void plot(istream& myStream) { </li></ul><ul><li> // while there's data </li></ul><ul><li>while (myStream) { </li></ul><ul><ul><ul><li>// get next poly </li></ul></ul></ul><ul><ul><ul><li>Poly *pPoly = readPoly(myStream); </li></ul></ul></ul><ul><ul><ul><li>try { </li></ul></ul></ul><ul><ul><ul><ul><ul><li>// Plot the polygon </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>pPoly->plotPoly(); </li></ul></ul></ul></ul></ul><ul><ul><ul><li>} catch (...) </li></ul></ul></ul><ul><ul><ul><li>{ </li></ul></ul></ul><ul><ul><ul><li>// delete object - exception </li></ul></ul></ul><ul><ul><ul><li>delete pPoly; </li></ul></ul></ul><ul><ul><ul><li>throw; // passes on exception </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>// delete object – no exception </li></ul></ul></ul><ul><ul><ul><li>delete pPoly; </li></ul></ul></ul><ul><li>} </li></ul><ul><li>} </li></ul>Code Duplication
  41. 41. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Litter code with try and catch blocks. </li></ul><ul><li>Duplicate cleanup code </li></ul><ul><ul><li>Normal paths and </li></ul></ul><ul><ul><li>Exceptional paths. </li></ul></ul><ul><ul><li>Executes anyway! </li></ul></ul><ul><li>Move the cleanup code that must always be executed into the destructor for an object local to plot(). </li></ul><ul><ul><li>Local objects are always destroyed when leaving a function, regardless of how that function is exited. </li></ul></ul><ul><li>The solution is to replace the pointer with an object that acts like a pointer </li></ul><ul><ul><li>aka, Smart Pointer </li></ul></ul>
  42. 42. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Smart pointer </li></ul><ul><ul><li>Is a C++ object </li></ul></ul><ul><ul><li>Stores pointers to dynamically allocated (heap / free store) objects </li></ul></ul><ul><ul><li>Improves raw pointers by implementing </li></ul></ul><ul><ul><ul><li>Construction & Destruction </li></ul></ul></ul><ul><ul><ul><li>Copying & Assignment </li></ul></ul></ul><ul><ul><ul><li>Dereferencing: </li></ul></ul></ul><ul><ul><ul><ul><li>operator–> </li></ul></ul></ul></ul><ul><ul><ul><ul><li>operator* </li></ul></ul></ul></ul><ul><ul><li>Grossly mimics raw pointer syntax & semantics </li></ul></ul>
  43. 43. Meyers [9] : Use destructors to prevent resource leaks <ul><li>auto_ptr </li></ul><ul><li>template<class T> </li></ul><ul><li>class auto_ptr { </li></ul><ul><li>public: </li></ul><ul><ul><li>// save ptr to object </li></ul></ul><ul><ul><li>auto_ptr(T *p = 0): ptr_(p) {} </li></ul></ul><ul><ul><li>// delete ptr to object </li></ul></ul><ul><ul><li>~auto_ptr() { delete ptr_; } </li></ul></ul><ul><ul><li>// Indirection </li></ul></ul><ul><ul><li>T* operator->() const { return ptr_; } </li></ul></ul><ul><ul><li>... </li></ul></ul><ul><li>private: </li></ul><ul><ul><li>// raw ptr to object </li></ul></ul><ul><ul><li>T *ptr_; </li></ul></ul><ul><li>}; </li></ul>
  44. 44. Meyers [9] : Use destructors to prevent resource leaks <ul><li>plot() for the Graphic Device (safe) </li></ul><ul><li>void plot(istream& myStream) { </li></ul><ul><ul><li>// while there's data </li></ul></ul><ul><ul><li>while (myStream) { </li></ul></ul><ul><ul><ul><li>// get next poly </li></ul></ul></ul><ul><ul><ul><li>auto_ptr<Poly> pPoly(readPoly(myStream)); </li></ul></ul></ul><ul><ul><ul><li>// Plot the polygon </li></ul></ul></ul><ul><ul><ul><li>pPoly->plotPoly(); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>pPoly->plotPoly(); means (pPoly.operator->())->plotPoly();
  45. 45. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Smart Pointers work as Holders of Resources </li></ul><ul><ul><li>RAII – Resource Acquisition is Initialization Idiom </li></ul></ul><ul><ul><li>Scoped Acquisition – Release Paradigm </li></ul></ul><ul><ul><ul><li>Acquires / Locks in Constructor </li></ul></ul></ul><ul><ul><ul><li>Releases / Unlocks in Destructor </li></ul></ul></ul><ul><ul><ul><li>Ensures safety on face of exceptions </li></ul></ul></ul>
  46. 46. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Window Handling in Windows OS (unsafe) </li></ul><ul><li>// This function leaks resources </li></ul><ul><li>// if an exception is thrown </li></ul><ul><li>void Display(const Information& info) { </li></ul><ul><ul><li>HANDLE w = CreateWindow( /* Creation Parameters */ ); </li></ul></ul><ul><ul><li>/* Data preparations */ </li></ul></ul><ul><ul><li>RenderWindow(w, info, /* Display Parameters */); </li></ul></ul><ul><ul><li>/* Data Cleanup */ </li></ul></ul><ul><ul><li>DestroyWindow(w); </li></ul></ul><ul><li>} </li></ul>
  47. 47. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Window Holder </li></ul><ul><li>// class for Holding (acquiring and </li></ul><ul><li>// releasing) a window handle </li></ul><ul><li>class WindowHolder { </li></ul><ul><li>public: </li></ul><ul><ul><li>WindowHolder(HANDLE h): w_(h) {} </li></ul></ul><ul><ul><li>~WindowHolder() { DestroyWindow(w_); } </li></ul></ul><ul><ul><li>operator HANDLE() { return w_; } </li></ul></ul><ul><li>private: </li></ul><ul><li>HANDLE w_; </li></ul><ul><ul><li>// Stop free functions being available </li></ul></ul><ul><ul><li>WindowHolder(const WindowHolder&); </li></ul></ul><ul><ul><li>WindowHolder& operator=(const WindowHolder&); </li></ul></ul><ul><li>}; </li></ul>
  48. 48. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Window Handling in Windows OS (safe) </li></ul><ul><li>// This function cleans up resources - always </li></ul><ul><li>void Display(const Information& info) { </li></ul><ul><ul><li>WindowHolder </li></ul></ul><ul><ul><ul><li>w(CreateWindow( /* Creation Parameters */ )); </li></ul></ul></ul><ul><ul><li>/* Data preparations */ </li></ul></ul><ul><ul><li>// WindowHandle is implicitly converted to HANDLE </li></ul></ul><ul><ul><li>RenderWindow(w, info, /* Display Parameters */); </li></ul></ul><ul><ul><li>/* Data Cleanup */ </li></ul></ul><ul><li>} </li></ul>
  49. 49. Meyers [9] : Use destructors to prevent resource leaks <ul><li>Morale </li></ul><ul><ul><li>Resources should be encapsulated inside objects. </li></ul></ul><ul><ul><li>Usually avoids resource leaks in the face of exceptions. </li></ul></ul>
  50. 50. More Questions <ul><li>What happens if an exception is thrown in the process of acquiring a resource, that is, in the constructor of a resource-acquiring class? </li></ul><ul><li>What happens if an exception is thrown during the automatic destruction of such resources? </li></ul>
  51. 51. Meyers [10] : Prevent resource leaks in constructors <ul><li>Consider:  </li></ul><ul><li>class T { ... }; </li></ul><ul><li>class T1 { public: T1(const T&); ... }; </li></ul><ul><li>class T2 { public: T2(const T&); ... }; </li></ul><ul><li>class A { </li></ul><ul><li>public: </li></ul><ul><ul><li>A(const T&, const T& = (T)0, const T& = (T)0); </li></ul></ul><ul><ul><li>~A(); </li></ul></ul><ul><ul><li>void f(const T&); ... </li></ul></ul><ul><li>private: </li></ul><ul><ul><li>T m_; </li></ul></ul><ul><ul><li>T1 *p1_; </li></ul></ul><ul><ul><li>T2 *p2_; </li></ul></ul><ul><li>}; </li></ul>
  52. 52. Meyers [10] : Prevent resource leaks in constructors <ul><li>Constructor (unsafe) / Destructor:  </li></ul><ul><li>A::A(const T& d, const T& s1, const T& s2): </li></ul><ul><ul><li>m_(d), p1_(0), p2_(0) </li></ul></ul><ul><li>{ </li></ul><ul><ul><li>if (s1 != (T)0) </li></ul></ul><ul><ul><ul><li>p1_ = new T1(s1); // 1 </li></ul></ul></ul><ul><ul><li>if (s2 != (T)0) </li></ul></ul><ul><ul><ul><li>p2_ = new T2(s2); // 2 </li></ul></ul></ul><ul><li>} </li></ul><ul><li>A::~A() </li></ul><ul><li>{ </li></ul><ul><ul><li>delete p1_; </li></ul></ul><ul><ul><li>delete p2_’ </li></ul></ul><ul><li>} </li></ul>
  53. 53. Meyers [10] : Prevent resource leaks in constructors <ul><li>Exception in body: </li></ul><ul><ul><li>operator (T) may throw. </li></ul></ul><ul><ul><li>T::operator != may throw </li></ul></ul><ul><ul><li>T::operator new may throw bad_alloc </li></ul></ul><ul><ul><li>Constructor for T1 or T2 may throw </li></ul></ul><ul><li>Exception at Line 1 is safe.  </li></ul><ul><ul><li>m_ gets destructed. </li></ul></ul><ul><li>Exception at Line 2 leaks p1_ .  </li></ul><ul><ul><li>A::~A() does not get called as the object is not there. </li></ul></ul><ul><li>A::A(const T& d, const T& s1, const T& s2):m_(d), p1_(0), p2_(0) { </li></ul><ul><ul><li>if (s1 != (T)0) p1_ = new T1(s1); // Line 1 </li></ul></ul><ul><ul><li>if (s2 != (T)0) p2_ = new T2(s2); // Line 2 } </li></ul></ul>
  54. 54. Meyers [10] : Prevent resource leaks in constructors <ul><li>Try Exception Fix by Dynamic Allocation </li></ul><ul><ul><li>Doesn’t work as pA is never assigned if the following throws </li></ul></ul><ul><ul><ul><li>T::operator new </li></ul></ul></ul><ul><ul><ul><li>Constructor for A </li></ul></ul></ul><ul><li>{ </li></ul><ul><ul><li>A *pA = 0; </li></ul></ul><ul><ul><li>try { </li></ul></ul><ul><ul><ul><li>pA = new A(d, s1, s2); </li></ul></ul></ul><ul><ul><ul><li>... </li></ul></ul></ul><ul><ul><li>} catch (...) { // catch all exceptions </li></ul></ul><ul><ul><ul><li>delete pA; // delete pA on an exception </li></ul></ul></ul><ul><ul><ul><li>throw; // Rethrow exception </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>delete pA; // delete pA normally </li></ul></ul><ul><li>} </li></ul>
  55. 55. Meyers [10] : Prevent resource leaks in constructors <ul><li>Constructor (safe) cleans up itself </li></ul><ul><li>A::A(const T& d, const T& s1, const T& s2): </li></ul><ul><ul><li>m_(d), p1_(0), p2_(0) </li></ul></ul><ul><li>{ </li></ul><ul><ul><li>try { </li></ul></ul><ul><ul><ul><li>if (s1 != (T)0) </li></ul></ul></ul><ul><ul><ul><ul><li>p1_ = new T1(s1); // 1 </li></ul></ul></ul></ul><ul><ul><ul><li>if (s2 != (T)0) </li></ul></ul></ul><ul><ul><ul><ul><li>p2_ = new T2(s2); // 2 </li></ul></ul></ul></ul><ul><ul><li>} catch (...) { </li></ul></ul><ul><ul><ul><li>delete p1_; </li></ul></ul></ul><ul><ul><ul><li>delete p2_; </li></ul></ul></ul><ul><ul><ul><li>throw; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>A::~A() </li></ul><ul><li>{ </li></ul><ul><ul><li>delete p1_; </li></ul></ul><ul><ul><li>delete p2_’ </li></ul></ul><ul><li>} </li></ul>
  56. 56. Meyers [10] : Prevent resource leaks in constructors <ul><li>Constructor (safe): w/o code duplication </li></ul><ul><li>A::A(const T& d, const T& s1, const T& s2): </li></ul><ul><ul><li>m_(d), p1_(0), p2_(0) </li></ul></ul><ul><li>{ </li></ul><ul><ul><li>try { </li></ul></ul><ul><ul><ul><li>if (s1 != (T)0) </li></ul></ul></ul><ul><ul><ul><ul><li>p1_ = new T1(s1); // 1 </li></ul></ul></ul></ul><ul><ul><ul><li>if (s2 != (T)0) </li></ul></ul></ul><ul><ul><ul><ul><li>p2_ = new T2(s2); // 2 </li></ul></ul></ul></ul><ul><ul><li>} catch (...) { </li></ul></ul><ul><ul><ul><li>CleanUp(); </li></ul></ul></ul><ul><ul><ul><li>throw; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>A::~A() </li></ul><ul><li>{ </li></ul><ul><ul><li>CleanUp(); </li></ul></ul><ul><li>} </li></ul><ul><li>A::CleanUp() </li></ul><ul><li>{ </li></ul><ul><ul><li>delete p1_; </li></ul></ul><ul><ul><li>delete p2_; </li></ul></ul><ul><li>} </li></ul>
  57. 57. Meyers [10] : Prevent resource leaks in constructors <ul><li>Reconsider:  </li></ul><ul><li>class T { ... }; </li></ul><ul><li>class T1 { public: T1(const T&); ... }; </li></ul><ul><li>class T2 { public: T2(const T&); ... }; </li></ul><ul><li>class A { </li></ul><ul><li>public: </li></ul><ul><ul><li>A(const T&, const T& = (T)0, const T& = (T)0); </li></ul></ul><ul><ul><li>~A(); </li></ul></ul><ul><ul><li>void f(const T&); ... </li></ul></ul><ul><li>private: </li></ul><ul><ul><li>T m_; </li></ul></ul><ul><ul><li>T1 * const p1_; </li></ul></ul><ul><ul><li>T2 * const p2_; </li></ul></ul><ul><li>}; </li></ul>
  58. 58. Meyers [10] : Prevent resource leaks in constructors <ul><li>Constructor (unsafe):  </li></ul><ul><li>Exception at Line 1 is safe.  </li></ul><ul><ul><li>m_ gets destructed. </li></ul></ul><ul><li>Exception at Line 2 leaks p1_ .  </li></ul><ul><ul><li>A::~A() does not get called. </li></ul></ul><ul><li>No try-catch on Initializer list – only expressions. </li></ul><ul><li>A::A(const T& d, const T& s1, const T& s2): </li></ul><ul><ul><li>m_(d), </li></ul></ul><ul><ul><li>p1_((s1 != (T)0)? new T1(s1): 0), // Line 1 </li></ul></ul><ul><ul><li>p2_((s2 != (T)0)? new T2(s2): 0) // Line 2 </li></ul></ul><ul><li>{ } </li></ul>
  59. 59. Meyers [10] : Prevent resource leaks in constructors <ul><li>Constructor (safe):  </li></ul><ul><li>T1* A::InitT1(const T&s) { </li></ul><ul><ul><li>if (s != (T)0) return new T1(s); </li></ul></ul><ul><ul><li>else return (T1*)0; } </li></ul></ul><ul><li>T2* A::InitT2(const T&s) { </li></ul><ul><ul><li>try { </li></ul></ul><ul><ul><ul><li>if (s != (T)0) return new T2(s); </li></ul></ul></ul><ul><ul><ul><li>else return (T2*)0; </li></ul></ul></ul><ul><ul><li>} catch (...) { </li></ul></ul><ul><ul><ul><li>delete p1_; </li></ul></ul></ul><ul><ul><ul><li>throw; } </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>A::A(const T& d, const T& s1, const T& s2): </li></ul><ul><ul><li>m_(d), p1_(InitT1(s1)), p2_(InitT2(s2)) { } </li></ul></ul>
  60. 60. Meyers [10] : Prevent resource leaks in constructors <ul><li>A better design:  </li></ul><ul><li>class T { ... }; </li></ul><ul><li>class T1 { public: T1(const T&); ... }; </li></ul><ul><li>class T2 { public: T2(const T&); ... }; </li></ul><ul><li>class A { </li></ul><ul><li>public: </li></ul><ul><ul><li>A(const T&, const T& = (T)0, const T& = (T)0); </li></ul></ul><ul><ul><li>~A(); </li></ul></ul><ul><ul><li>void f(const T&); ... </li></ul></ul><ul><li>private: </li></ul><ul><ul><li>T m_; </li></ul></ul><ul><ul><li>const auto_ptr<T1> p1_; </li></ul></ul><ul><ul><li>const auto_ptr<T2> p2_; </li></ul></ul><ul><li>}; </li></ul>
  61. 61. Meyers [10] : Prevent resource leaks in constructors <ul><li>Constructor (safe by design):  </li></ul><ul><li>Exception at Line 1 is safe.  </li></ul><ul><ul><li>m_ gets destructed. </li></ul></ul><ul><li>Exception at Line 2 is safe.  </li></ul><ul><ul><li>m_ & p1_ get destructed. </li></ul></ul><ul><li>// Constructor </li></ul><ul><li>A::A(const T& d, const T& s1, const T& s2): </li></ul><ul><ul><li>m_(d), </li></ul></ul><ul><ul><li>p1_((s1 != (T)0)? new T1(s1): 0), // Line 1 </li></ul></ul><ul><ul><li>p2_((s2 != (T)0)? new T2(s2): 0) // Line 2 </li></ul></ul><ul><li>{ } </li></ul>// Destructor A::~A() { }
  62. 62. Meyers [10] : Prevent resource leaks in constructors <ul><li>Moral </li></ul><ul><ul><li>Replace pointer class members with their corresponding auto_ptr objects </li></ul></ul><ul><ul><ul><li>Fortifies constructors against resource leaks in the presence of exceptions, </li></ul></ul></ul><ul><ul><ul><li>Eliminates the need to manually deallocate resources in destructors, and </li></ul></ul></ul><ul><ul><ul><li>Allows const member pointers to be handled in the same graceful fashion as non-const pointers. </li></ul></ul></ul>
  63. 63. Meyers [11] : Prevent exceptions from leaving destructors <ul><li>A destructor is called in two situations </li></ul><ul><ul><li>When an object is destroyed under “normal” conditions </li></ul></ul><ul><ul><ul><li>When it goes out of scope or </li></ul></ul></ul><ul><ul><ul><li>Is explicitly deleted. </li></ul></ul></ul><ul><ul><li>When an object is destroyed by the exception-handling mechanism during the stack-unwinding part of “exception propagation”. </li></ul></ul>
  64. 64. Meyers [11] : Prevent exceptions from leaving destructors <ul><li>Recap </li></ul><ul><ul><li>If an exception is thrown when another exception is active, terminate() is called and the program immediately terminates. </li></ul></ul><ul><ul><li>From within a destructor, there is no robust way to determine if an exception is active. </li></ul></ul>
  65. 65. Meyers [11] : Prevent exceptions from leaving destructors <ul><li>Consider </li></ul><ul><li>class Session { </li></ul><ul><ul><li>public: </li></ul></ul><ul><ul><ul><li>Session(); </li></ul></ul></ul><ul><ul><ul><li>~Session(); </li></ul></ul></ul><ul><ul><ul><li>... </li></ul></ul></ul><ul><ul><li>private: </li></ul></ul><ul><ul><ul><li>static void logCreation(Session *); </li></ul></ul></ul><ul><ul><ul><li>static void logDestruction(Session *); </li></ul></ul></ul><ul><li>}; </li></ul><ul><li>Session::~Session() { </li></ul><ul><ul><li>// Fatal to throw here </li></ul></ul><ul><ul><li>logDestruction(this); </li></ul></ul><ul><li>}; </li></ul>
  66. 66. Meyers [11] : Prevent exceptions from leaving destructors <ul><li>Manage the exceptions </li></ul><ul><li>Session::~Session() { </li></ul><ul><ul><li>try { </li></ul></ul><ul><ul><ul><li>logDestruction(this); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>catch (...) { </li></ul></ul><ul><ul><ul><li>// Fatal again if operator<<() throws </li></ul></ul></ul><ul><ul><ul><li>cerr << &quot;Unable to log destruction of Session object&quot; </li></ul></ul></ul><ul><ul><ul><ul><li><< &quot;at address &quot; </li></ul></ul></ul></ul><ul><ul><ul><ul><li><< this </li></ul></ul></ul></ul><ul><ul><ul><ul><li><< &quot;. &quot;; </li></ul></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>}; </li></ul>
  67. 67. Meyers [11] : Prevent exceptions from leaving destructors <ul><li>Bite the dust – swallow the exceptions </li></ul><ul><li>Session::~Session() { </li></ul><ul><ul><li>try { </li></ul></ul><ul><ul><ul><li>logDestruction(this); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>catch (...) { } </li></ul></ul><ul><li>}; </li></ul>
  68. 68. Meyers [11] : Prevent exceptions from leaving destructors <ul><li>Moral </li></ul><ul><ul><li>Keep exceptions from propagating out of destructors. </li></ul></ul><ul><ul><ul><li>Prevents terminate from being called during the stack-unwinding part of exception propagation. </li></ul></ul></ul><ul><ul><ul><li>Helps ensure that destructors always accomplish everything they are supposed to accomplish. </li></ul></ul></ul>
  69. 69. Meyers [12] : Throwing an exception differs from passing a parameter or calling a virtual function <ul><li>Control does not return to the throw site. </li></ul><ul><li>Throw always copies the object. </li></ul><ul><li>Catch needs to clean-up the thrown object. </li></ul><ul><li>Parameter Matching is exact for Catch and done with the static type </li></ul><ul><li>Overloaded Catch clauses are tried in lexical order. </li></ul>
  70. 70. Meyers [13] : Catch exceptions by reference
  71. 71. Meyers [14] : Use exception specifications judiciously
  72. 72. Meyers [15] : Understand the costs of exception handling
  73. 73. Handling Exceptions in C & C++ References & Credits
  74. 74. References <ul><li>Handling Exceptions: Part 1 – 4 </li></ul><ul><ul><li>Robert Schmidt </li></ul></ul><ul><li>Modern C++ Design: Generic Programming & Design Pattern Applied </li></ul><ul><ul><li>Andrei Alexandrescu </li></ul></ul><ul><li>Exceptional C++ & More Exceptional C++ </li></ul><ul><ul><li>Herb Sutter </li></ul></ul><ul><li>Effective C++ & More Effective C++ </li></ul><ul><ul><li>Scott Meyers </li></ul></ul><ul><li>Standard Features Missing From VC++ 7.1. Part I: Exception Specifications </li></ul><ul><ul><li>Nemanja Trifunovic http://www.codeproject.com/cpp/stdexceptionspec.asp </li></ul></ul><ul><li>A Pragmatic Look at Exception Specifications </li></ul><ul><ul><li>http://www.gotw.ca/publications/mill22.htm </li></ul></ul>
  75. 75. Credits / Acknowledgements
  76. 76. Thank You

×