Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Handling Exceptions In C & C++[Part A]


Published on

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

Published in: Education
  • Be the first to comment

Handling Exceptions In C & C++[Part A]

  1. 1. Oct 04, 2007 Handling Exceptions in C++ Dr. Partha Pratim Das Interra Systems (India) Pvt. Ltd. PART A
  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 A
  6. 6. Exception Fundamentals Basic Notions
  7. 7. An exceptional circumstance is not necessarily an error <ul><li>What is Exception? </li></ul><ul><ul><li>Conditions that arise infrequently and unexpectedly, generally betray a program error, and require a considered programmatic response. </li></ul></ul><ul><ul><ul><li>Runtime Error – yes, but not necessarily </li></ul></ul></ul><ul><li>Consequence </li></ul><ul><ul><li>May render the program crippled or dead, sometimes taking the entire system down with it. </li></ul></ul><ul><li>Defensive Techniques </li></ul><ul><ul><li>Often trades one problem (crashing exceptions) for another (more tangled design and code). </li></ul></ul>
  8. 8. I had thought through the design, but … <ul><li>Unexpected Systems State </li></ul><ul><ul><li>Exhaustion of Resources </li></ul></ul><ul><ul><ul><li>Low Free store memory </li></ul></ul></ul><ul><ul><ul><li>Low Disk Space </li></ul></ul></ul><ul><ul><li>Pushing to a full stack </li></ul></ul><ul><li>External Events </li></ul><ul><ul><li>^C </li></ul></ul><ul><ul><li>Socket Event </li></ul></ul>
  9. 9. My program was correct, well tested, but for … <ul><li>Logical Errors </li></ul><ul><ul><li>Pop from an empty stack </li></ul></ul><ul><ul><li>Resource Errors – UMR, NPR, NPW, FMR, FMW, FMM, FNH, FUM, ABR, ABW, FIU, … </li></ul></ul><ul><ul><ul><li>MLK, PLK are not exceptions </li></ul></ul></ul><ul><li>Runtime Errors </li></ul><ul><ul><li>Arithmetic Overflow / Underflow </li></ul></ul><ul><ul><li>Out of Range </li></ul></ul>
  10. 10. I managed to put the system out of gear … <ul><li>Undefined Operation </li></ul><ul><ul><li>Division by 0 </li></ul></ul>
  11. 11. Do I need Exception Handling? <ul><li>Exception handling is a mechanism that separates code that detects and handles exceptional circumstances from the rest of your program. </li></ul><ul><ul><li>Normal Flow </li></ul></ul><ul><ul><li>Exceptional Flow </li></ul></ul>“ Exceptions are C++s means of separating error reporting from error handling ”– Bjarne Stroustrup
  12. 12. The Classical Dilemma <ul><li>Library can detect runtime errors but does not in general have any idea what to do about them. </li></ul><ul><li>Application using a library may know how to cope with such errors but cannot detect them. </li></ul>
  13. 13. Types of Exceptions <ul><li>Asynchronous Exceptions: </li></ul><ul><ul><li>Exceptions that come unexpectedly </li></ul></ul><ul><ul><li>Example – an Interrupt in a program </li></ul></ul><ul><ul><li>Takes control away from the executing thread context to a context that is different from that which caused the exception. </li></ul></ul><ul><li>Synchronous Exceptions: </li></ul><ul><ul><li>Planned Exceptions </li></ul></ul><ul><ul><li>Handled in an organized manner. </li></ul></ul><ul><ul><li>The most common type of synchronous exception is implemented as a &quot; throw .&quot; </li></ul></ul>
  14. 14. Exception Stages <ul><li>[1] Error Incidence </li></ul><ul><ul><li>Synchronous (S/W) Logical Error </li></ul></ul><ul><ul><li>Asynchronous (H/W) Interrupt  S/W Interrupt </li></ul></ul><ul><li>[2] Create Object & Raise Exception </li></ul><ul><ul><li>An Exception Object can be of any complete type </li></ul></ul><ul><ul><li>An int to a full blown C++ class object </li></ul></ul><ul><li>[3] Detect Exception </li></ul><ul><ul><li>Polling – Software Tests </li></ul></ul><ul><ul><li>Notification – Control (Stack) Adjustments </li></ul></ul>
  15. 15. Exception Stages <ul><li>[4] Handle Exception </li></ul><ul><ul><li>Ignore : hope someone else handles it. </li></ul></ul><ul><ul><li>Act : but allow others to handle it afterwards. </li></ul></ul><ul><ul><li>Own : take complete ownership. </li></ul></ul>
  16. 16. Exception Stages <ul><li>[5] Recover from Exception </li></ul><ul><ul><li>Continue Execution: If handled inside the program </li></ul></ul><ul><ul><ul><li>Resuming Exceptions – PL/I, Eiffel (limited), VC++ (SEH) </li></ul></ul></ul><ul><ul><ul><ul><li>From where the exception was generated . </li></ul></ul></ul></ul><ul><ul><ul><li>Terminating Exceptions – Ada, Modula, C++, Java </li></ul></ul></ul><ul><ul><ul><ul><li>From where the exception was handled . </li></ul></ul></ul></ul><ul><ul><li>Abort Execution: If handled outside the program </li></ul></ul>
  17. 17. Exception Stages <ul><li>int f() { </li></ul><ul><ul><li>int error; </li></ul></ul><ul><ul><li>/* ... */ </li></ul></ul><ul><ul><li>if (error) /* Stage 1: error occurred */ </li></ul></ul><ul><ul><ul><li>return -1; /* Stage 2: generate exception object */ </li></ul></ul></ul><ul><ul><li>/* ... */ </li></ul></ul><ul><li>} </li></ul><ul><li>int main(void) { </li></ul><ul><ul><li>if (f() != 0) /* Stage 3: detect exception */ </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><ul><li>/* Stage 4: handle exception */ </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>/* Stage 5: recover */ </li></ul></ul><ul><li>} </li></ul>
  18. 18. Exceptions in C A Recap of Error Handling Techniques
  19. 19. Support for Exceptions in C <ul><li>Language Feature </li></ul><ul><ul><li>Return Value & Parameters </li></ul></ul><ul><ul><li>Local goto </li></ul></ul><ul><li>Standard Library Support </li></ul><ul><ul><li>Global Variables </li></ul></ul><ul><ul><li>Abnormal Termination </li></ul></ul><ul><ul><li>Conditional Termination </li></ul></ul><ul><ul><li>Non-Local goto </li></ul></ul><ul><ul><li>Signals </li></ul></ul>
  20. 20. Exceptions in C : Language Features <ul><li>Return Value & Parameters </li></ul><ul><li>Local goto </li></ul>
  21. 21. Exceptions in C : Return Value & Parameters <ul><li>Function Return Value Mechanism </li></ul><ul><ul><li>Created by the Callee as Temporary Objects </li></ul></ul><ul><ul><li>Passed onto the Caller </li></ul></ul><ul><ul><li>Caller checks for Error Conditions </li></ul></ul>if ((p = malloc(n)) == NULL) /* ... */ if ((c = getchar()) == EOF) /* ... */ if (A *p = dynamic_cast<A*>(pObj)) /* ... */ else /* ... */
  22. 22. Exceptions in C : Return Value & Parameters <ul><li>Function Return Value is good, because </li></ul><ul><ul><li>Are accessible by exactly two parties </li></ul></ul><ul><ul><ul><li>the one generating the exception, and </li></ul></ul></ul><ul><ul><ul><li>the one detecting it. </li></ul></ul></ul><ul><ul><li>Take on exactly one value. </li></ul></ul><ul><ul><li>Cannot have their names hidden by user declarations. </li></ul></ul><ul><ul><ul><li>As they are nameless </li></ul></ul></ul><ul><ul><li>Are typically thread-safe. </li></ul></ul>
  23. 23. Exceptions in C : Return Value & Parameters <ul><li>Stages </li></ul><ul><ul><li>2: Raise </li></ul></ul><ul><ul><ul><li>Incidence of Error causes the Error Value to be returned by the Function Call </li></ul></ul></ul><ul><ul><li>3: Detect </li></ul></ul><ul><ul><ul><li>Calling Function detects the Error Value and takes necessary decisions </li></ul></ul></ul>
  24. 24. Exceptions in C : Return Value & Parameters <ul><li>Example 1 </li></ul>int Push(int i) { if (top_ == size-1) // Incidence return 0; // Raise else stack_[++top_] = i; return 1; } int main() { int x; // ... if (!Push(x)) // Detect { // Handling } // Recovery }
  25. 25. Exceptions in C : Return Value & Parameters <ul><li>Example 2 </li></ul><ul><ul><li>HRESULT (Windows) Type </li></ul></ul><ul><ul><li>Returned by COM functions / interface methods </li></ul></ul><ul><ul><li>Returned for success, warning, & error values. </li></ul></ul><ul><ul><li>Not really handles to anything; </li></ul></ul><ul><ul><ul><li>32-bit values with several fields encoded in the value. </li></ul></ul></ul><ul><ul><li>Zero indicates success, and a non-zero result indicates failure. </li></ul></ul>
  26. 26. Exceptions in C : Return Value & Parameters <ul><li>Example 2 </li></ul><ul><ul><li>COM Interfaces Support IUnknown:: QueryInterface to get a pointer to a specified interface on an object to which a client currently holds an interface pointer. </li></ul></ul><ul><ul><ul><li>HRESULT IUnknown::QueryInterface( </li></ul></ul></ul><ul><ul><ul><ul><li>REFIID iid , </li></ul></ul></ul></ul><ul><ul><ul><ul><li>void ** ppvObject ); </li></ul></ul></ul></ul><ul><ul><li>Return Value </li></ul></ul><ul><ul><ul><li>S_OK if the interface is supported, </li></ul></ul></ul><ul><ul><ul><li>E_NOINTERFACE if not. </li></ul></ul></ul>
  27. 27. Exceptions in C : Return Value & Parameters <ul><li>Function (output) Parameter Mechanism </li></ul><ul><ul><li>Return values can be ignored and lost. </li></ul></ul><ul><ul><li>Outbound parameters are bound to arguments </li></ul></ul><ul><ul><ul><li>Compared to return values, parameters form a tighter coupling between a function and its caller. </li></ul></ul></ul><ul><ul><li>Outbound parameters, offer multiple logical return values. </li></ul></ul><ul><ul><li>Return values are temporary </li></ul></ul><ul><ul><ul><li>RV Lifetime limited to the function call </li></ul></ul></ul><ul><ul><ul><li>Arguments have a lifetime beyond the function call. </li></ul></ul></ul>
  28. 28. Exceptions in C : Local goto <ul><li>Local goto Mechanism </li></ul><ul><ul><li>[ Source ] </li></ul></ul><ul><ul><ul><li>Escapes : Gets Control out of a Deep Nested Loop </li></ul></ul></ul><ul><ul><li>[ Destination ] </li></ul></ul><ul><ul><ul><li>Refactors : Actions from Multiple Points of Error Inception </li></ul></ul></ul><ul><ul><ul><ul><li>Separates Error Handling Code from the rest </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Enhances Cleanup Code by Reuse </li></ul></ul></ul></ul>
  29. 29. Exceptions in C : Local goto <ul><li>Local goto is a group of C Features </li></ul><ul><ul><li>goto Label ; </li></ul></ul><ul><ul><ul><li>Escapes & Refactors </li></ul></ul></ul><ul><ul><li>break ; & continue </li></ul></ul><ul><ul><ul><li>Escapes </li></ul></ul></ul><ul><ul><li>default switch case </li></ul></ul><ul><ul><ul><li>Refactors </li></ul></ul></ul>
  30. 30. Exceptions in C : Local goto <ul><li>Stages </li></ul><ul><ul><li>2: Raise </li></ul></ul><ul><ul><ul><li>When Error occurs jump to a Label at End of Function </li></ul></ul></ul><ul><ul><li>3: Detect </li></ul></ul><ul><ul><ul><li>At the Target Label Set the Error Value and Do Code Clean Up </li></ul></ul></ul>
  31. 31. Exceptions in C : Local goto <ul><li>Example </li></ul><ul><ul><li>_PHNDLR __cdecl signal( </li></ul></ul><ul><ul><ul><ul><li>int signum, </li></ul></ul></ul></ul><ul><ul><ul><ul><li>_PHNDLR sigact) </li></ul></ul></ul></ul><ul><ul><li>Return: </li></ul></ul><ul><ul><ul><li>Success: </li></ul></ul></ul><ul><ul><ul><ul><li>Signal returns the previous value of the signal handling function (e.g., SIG_DFL, SIG_IGN, etc., or [function address]). </li></ul></ul></ul></ul><ul><ul><ul><li>Failure: </li></ul></ul></ul><ul><ul><ul><ul><li>Signal returns -1 and errno is set to EINVAL. The error return is generally taken on bogus input values. </li></ul></ul></ul></ul>
  32. 32. Exceptions in C : Local goto _PHNDLR __cdecl signal(int signum, _PHNDLR sigact) { // Lifted from VC98CRTSRCWINSIG.C ... /* Check for sigact support */ if ( (sigact == ...) ) goto sigreterror; /* Not exceptions in the host OS. */ if ( (signum == ... ) { ... goto sigreterror; } else { ... goto sigretok; } /* Exceptions in the host OS. */ if ( (signum ...) ) goto sigreterror; ... sigretok: return(oldsigact); sigreterror: errno = EINVAL; return(SIG_ERR); }
  33. 33. Exceptions in C : Standard Library <ul><li>Global Variables </li></ul><ul><li>Abnormal Termination </li></ul><ul><li>Conditional Termination </li></ul><ul><li>Non-Local goto </li></ul><ul><li>Signals </li></ul>
  34. 34. Exceptions in C : Global Variables <ul><li>GV Mechanism </li></ul><ul><ul><li>Use a designated Global Error Variable </li></ul></ul><ul><ul><li>Set it on error </li></ul></ul><ul><ul><li>Poll / Check it for detection </li></ul></ul>
  35. 35. Exceptions in C : Global Variables <ul><li>GV Mechanism in Standard Library </li></ul><ul><ul><li><errno.h> / <cerrno> Header defines “ errno ” plus several values it can take </li></ul></ul><ul><ul><ul><li>EDOM :: Domain Error </li></ul></ul></ul><ul><ul><ul><li>ERANGE :: Out of Range Error </li></ul></ul></ul><ul><ul><ul><li>EILSEQ :: Multi-Byte Sequence Error </li></ul></ul></ul><ul><ul><ul><li>0 :: No Error </li></ul></ul></ul><ul><ul><li>Used within <math.h> & <stdio.h> functions. </li></ul></ul><ul><ul><li>errno is set to 0 at program start </li></ul></ul><ul><ul><li>errno needs to be cleared before error incidence </li></ul></ul>
  36. 36. Exceptions in C : Global Variables <ul><li>Windows Mechanism </li></ul><ul><ul><li><winbase.h> / <windows.h> </li></ul></ul><ul><ul><li>DWORD GetLastError(void); </li></ul></ul><ul><ul><ul><li>Retrieves the calling thread's last-error code value. </li></ul></ul></ul><ul><ul><li>void SetLastError( DWORD dwErrCode ); </li></ul></ul><ul><ul><ul><li>Sets the last-error code for the calling thread. </li></ul></ul></ul>
  37. 37. Exceptions in C : Global Variables <ul><li>Stages </li></ul><ul><ul><li>1: Incidence </li></ul></ul><ul><ul><ul><li>Initialize “errno” number to 0 and call Library routine </li></ul></ul></ul><ul><ul><li>2: Raise </li></ul></ul><ul><ul><ul><li>Library Routine sets “errno” to appropriate value </li></ul></ul></ul><ul><ul><li>3: Detect </li></ul></ul><ul><ul><ul><li>User Code interrogates “errno” values for match with EDOM, ERANGE or EILSEQ </li></ul></ul></ul>
  38. 38. Exceptions in C : Global Variables <ul><li>Example 1 </li></ul>
  39. 39. Exceptions in C : Global Variables <ul><li>Example 2: Windows SDK </li></ul><ul><ul><li>To create a window, use: </li></ul></ul><ul><ul><ul><li>HWND CreateWindowEx(…); </li></ul></ul></ul><ul><ul><li>Return Value </li></ul></ul><ul><ul><ul><li>If the function succeeds, the return value is a handle to the new window. </li></ul></ul></ul><ul><ul><ul><li>If the function fails, the return value is NULL. </li></ul></ul></ul><ul><ul><ul><ul><li>To get extended error information, call GetLastError . </li></ul></ul></ul></ul>
  40. 40. Exceptions in C : Abnormal Termination <ul><li>Abnormal Termination Mechanism </li></ul><ul><ul><li>Program Halting Functions provided by <stdlib.h> / <cstdlib> Header </li></ul></ul><ul><ul><li>abort() </li></ul></ul><ul><ul><ul><li>Catastrophic Program Failure </li></ul></ul></ul><ul><ul><li>exit() </li></ul></ul><ul><ul><ul><li>Code Clean up via atexit() Registrations </li></ul></ul></ul><ul><ul><li>atexit() </li></ul></ul><ul><ul><ul><li>Handlers called in reverse order of their Registrations </li></ul></ul></ul>
  41. 41. Exceptions in C : Abnormal Termination <ul><li>abort() </li></ul><ul><ul><li>Abnormal program termination. </li></ul></ul><ul><ul><li>Run-time diagnostic and self-destruction. </li></ul></ul><ul><ul><li>May or may not flush / close opened files or remove temporary files. </li></ul></ul><ul><li>exit() </li></ul><ul><ul><li>Civilized program termination. </li></ul></ul><ul><ul><li>Closes opened files and returning a status. </li></ul></ul><ul><ul><li>C alls handlers registered via atexit() . </li></ul></ul>
  42. 42. Exceptions in C : Abnormal Termination <ul><li>Signature: int atexit(void (*pFunction)(void)); </li></ul><ul><li>Use atexit() to register a function with signature </li></ul><ul><ul><ul><li>void CallbackFunction(void); </li></ul></ul></ul><ul><li>Registered functions called from Runtime after main() exits </li></ul><ul><li>If multiple functions are registered, then the calls will made be in the reverse order of registration (LIFO) </li></ul><ul><li>Used by: </li></ul><ul><ul><li>Compiler for Local Static Objects </li></ul></ul><ul><ul><li>Application Programmer for function call beyond main() </li></ul></ul>
  43. 43. Exceptions in C : Abnormal Termination <ul><li>Stages </li></ul><ul><ul><li>4: Handle </li></ul></ul><ul><ul><ul><li>Functions to be called by atexit() are registered in reverse order </li></ul></ul></ul><ul><ul><li>5: Recover </li></ul></ul><ul><ul><ul><li>Clean Up done after exit() via the calling functions registered at atexit() </li></ul></ul></ul>
  44. 44. Exceptions in C : Abnormal Termination <ul><li>Example </li></ul>
  45. 45. Exceptions in C : Conditional Termination <ul><li>Conditional Termination Mechanism </li></ul><ul><ul><li>Diagnostic ASSERT macro defined in <assert.h> / <cassert> Header </li></ul></ul><ul><ul><li>Assertions valid when NDEBUG macro is not defined (debug build is done) </li></ul></ul><ul><ul><li>Assert calls internal function, reports the source file details and then Terminates </li></ul></ul>
  46. 46. Exceptions in C : Conditional Termination <ul><li>Stages </li></ul><ul><ul><li>3: Detect </li></ul></ul><ul><ul><ul><li>Evaluates a Pre-condition Check </li></ul></ul></ul><ul><ul><li>4: Handle </li></ul></ul><ul><ul><ul><li>Calls Internal Functions (eg, _assert()) </li></ul></ul></ul><ul><ul><li>5: Recover </li></ul></ul><ul><ul><ul><li>Details the failed condition and then calls abort() </li></ul></ul></ul>
  47. 47. Exceptions in C : Conditional Termination <ul><li>ASSERT Macro </li></ul>#if defined NDEBUG #define ASSERT(condition) ((void) 0) #else #define ASSERT(condition) _assert((condition), #condition, __FILE__, __LINE__) #endif
  48. 48. Exceptions in C : Conditional Termination <ul><li>Example </li></ul>
  49. 49. Exceptions in C : Conditional Termination <ul><li>Why is ASSERT a macro? </li></ul><ul><ul><li>Stringize operation on the Expression </li></ul></ul><ul><ul><li>Manifest constants: File Name & Line No </li></ul></ul><ul><li>Can the test in ASSERT have side effect? </li></ul><ul><ul><li>No. As, ASSERT works in debug build alone </li></ul></ul><ul><li>What is a VERIFY macro? </li></ul>#if defined NDEBUG #define VERIFY(condition) (condition) /* Survives */ #else #define VERIFY(condition) _assert((condition), #condition, __FILE__, __LINE__) #endif
  50. 50. Exceptions in C : Non-Local goto <ul><li>Non-Local goto Mechanism </li></ul><ul><ul><li>setjmp() and longjmp() functions provided in <setjmp.h> Header along with collateral type jmp_buf </li></ul></ul><ul><ul><li>setjmp(jmp_buf) </li></ul></ul><ul><ul><ul><li>Sets the Jump point filling up the jmp_buf object with the current program context </li></ul></ul></ul><ul><ul><li>longjmp(jmp_buf, int) </li></ul></ul><ul><ul><ul><li>Effects a Jump to the context of the jmp_buf object </li></ul></ul></ul><ul><ul><ul><li>Control return to setjmp call last called on jmp_buf </li></ul></ul></ul>
  51. 51. Exceptions in C : Non-Local goto <ul><li>The Dynamics </li></ul>void f() { A a; if (setjmp(jbuf) == 0) { B b; g(); h(); } else { cout << ex.what(); } return; } <ul><ul><li>jmp_buf jbuf; </li></ul></ul><ul><ul><li>void g() </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>A a; </li></ul></ul><ul><ul><li>UsrExcp ex(“From g()”); </li></ul></ul><ul><ul><li>longjmp(jbuf, 1); </li></ul></ul><ul><ul><li>return; </li></ul></ul><ul><ul><li>} </li></ul></ul>
  52. 52. Exceptions in C : Non-Local goto <ul><li>Stages </li></ul><ul><ul><li>2: Raise </li></ul></ul><ul><ul><ul><li>setjmp saves the program context in ( jmp_buf ) </li></ul></ul></ul><ul><ul><ul><li>On Error longjmp returns control to the saved context </li></ul></ul></ul><ul><ul><ul><li>Provides an integer as the exception object </li></ul></ul></ul><ul><ul><li>3: Detect </li></ul></ul><ul><ul><ul><li>The User Code branches to proper handler on Integer Exception object </li></ul></ul></ul>
  53. 53. Exceptions in C : Non-Local goto <ul><li>Example 1 </li></ul>
  54. 54. Exceptions in C : Non-Local goto <ul><li>Example 2 </li></ul><ul><ul><li>Write a safe Solver for Quadratic Equations with Integer Coefficients. </li></ul></ul><ul><ul><ul><li>The equation as ax 2 +bx+c = 0 where a , b and c are integers. </li></ul></ul></ul><ul><ul><ul><li>Use the general formula for solving a quadratic equation. </li></ul></ul></ul><ul><ul><ul><li>The solver is expected to work in an infinite loop - read coefficients and print solutions. </li></ul></ul></ul><ul><ul><ul><li>Normal program termination is by ^C . </li></ul></ul></ul>
  55. 55. Exceptions in C : Non-Local goto <ul><li>Example 2 </li></ul><ul><ul><li>The Exception conditions are: </li></ul></ul><ul><ul><ul><li>Input Insanity. </li></ul></ul></ul><ul><ul><ul><ul><li>Incidence : a == b == 0 . </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Handling/Recovery : Take fresh inputs; proceed as normal. </li></ul></ul></ul></ul><ul><ul><ul><li>Linear Equation. </li></ul></ul></ul><ul><ul><ul><ul><li>Incidence : a == 0, b != 0 . </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Handling/Recovery : Use a different solver function for the linear case (-c/b). Branch to this function for solution. </li></ul></ul></ul></ul><ul><ul><ul><li>Complex Roots. </li></ul></ul></ul><ul><ul><ul><ul><li>Incidence : Discriminant is negative. </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Handling/Recovery : Graceful termination with an apology . </li></ul></ul></ul></ul>
  56. 56. Exceptions in C : Non-Local goto <ul><li>Notes </li></ul><ul><ul><li>jmp_buf stores the Environment (Program Context) comprising SP, FP, PC and registers </li></ul></ul><ul><ul><li>jmp_buf is system dependent </li></ul></ul><ul><ul><li>The size of a jmp_buf is (around 2000) </li></ul></ul><ul><ul><ul><li>6 pointers on Pentium/Linux, </li></ul></ul></ul><ul><ul><ul><li>19 on Sparc/Solaris, and </li></ul></ul></ul><ul><ul><ul><li>84 on Alpha/Digital-Unix. </li></ul></ul></ul><ul><ul><li>On save, setjmp returns 0. </li></ul></ul><ul><ul><li>#define _JBLEN  9 </li></ul></ul><ul><ul><li>typedef struct { int _jb[_JBLEN + 1]; } jmp_buf[1]; </li></ul></ul>
  57. 57. Exceptions in C : Non-Local goto <ul><li>Notes </li></ul><ul><ul><li>longjmp loads saved Environment from jmp_buf and sets return value to int Exception Object. </li></ul></ul><ul><ul><ul><li>longjmp never returns (cannot) </li></ul></ul></ul><ul><ul><ul><li>Control transfers back to setjmp </li></ul></ul></ul><ul><ul><ul><li>Stack Cutting is performed </li></ul></ul></ul><ul><ul><li>jmp_buf gets bad once control leaves the function scope from where setjmp was called. </li></ul></ul><ul><ul><li>Stack Cutting does not Finalize! (Cannot, actually) </li></ul></ul>
  58. 58. Exceptions in C : Signals <ul><li>Signal Mechanism </li></ul><ul><ul><li>Header <signal.h> </li></ul></ul><ul><ul><li>raise() </li></ul></ul><ul><ul><ul><li>Sends a signal to the executing program. </li></ul></ul></ul><ul><ul><li>signal() </li></ul></ul><ul><ul><ul><li>Registers interrupt signal handler. It returns the previous handler associated with the given signal. </li></ul></ul></ul><ul><ul><li>Converts h/w interrupts to s/w interrupts </li></ul></ul>
  59. 59. Exceptions in C : Typical Signals <ul><li>SIGABRT </li></ul><ul><ul><li>Abnormal termination. The default action terminates the calling program with exit code 3. </li></ul></ul><ul><li>SIGFPE </li></ul><ul><ul><li>Floating-point error, such as overflow, division by zero, or invalid operation. The default action terminates the calling program. </li></ul></ul><ul><li>SIGILL </li></ul><ul><ul><li>Illegal instruction. The default action terminates the calling program. </li></ul></ul>
  60. 60. Exceptions in C : Typical Signals <ul><li>SIGINT </li></ul><ul><ul><li>CTRL+C interrupt. The default action issues INT 23H. </li></ul></ul><ul><li>SIGSEGV </li></ul><ul><ul><li>Illegal storage access. The default action terminates the calling program. </li></ul></ul><ul><li>SIGTERM </li></ul><ul><ul><li>Termination request sent to the program. The default action terminates the calling program. </li></ul></ul>
  61. 61. Exceptions in C : Signals <ul><li>Stages </li></ul><ul><ul><li>1: Incidence </li></ul></ul><ul><ul><ul><li>External event </li></ul></ul></ul><ul><ul><ul><li>Hardware Interrupt </li></ul></ul></ul><ul><ul><li>2: Raise </li></ul></ul><ul><ul><ul><li>Signal / Software Interrupt created </li></ul></ul></ul><ul><ul><li>3: Detect </li></ul></ul><ul><ul><ul><li>Search of Registered Handler </li></ul></ul></ul><ul><ul><ul><li>Invocation of Handler </li></ul></ul></ul>
  62. 62. Exceptions in C : Signals <ul><li>Stages </li></ul><ul><ul><li>4: Handle </li></ul></ul><ul><ul><ul><li>Terminate </li></ul></ul></ul><ul><ul><ul><li>Synchronize with Main code </li></ul></ul></ul><ul><ul><li>5: Recover </li></ul></ul><ul><ul><ul><li>Termination </li></ul></ul></ul><ul><ul><ul><li>Abort </li></ul></ul></ul>
  63. 63. Exceptions in C : Signals <ul><li>Example </li></ul><ul><ul><li>// Use signal to attach a signal </li></ul></ul><ul><ul><li>// handler to the abort routine </li></ul></ul><ul><ul><li>#include <stdio.h> </li></ul></ul><ul><ul><li>#include <stdlib.h> </li></ul></ul><ul><ul><li>#include <signal.h> </li></ul></ul><ul><ul><li>#include <tchar.h> </li></ul></ul><ul><ul><li>void SignalHandler(int signal) { </li></ul></ul><ul><ul><li>printf(&quot;Application aborting... &quot;); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>int main() { </li></ul></ul><ul><ul><li>typedef void (*SignalHandlerPointer)(int); </li></ul></ul><ul><ul><li>SignalHandlerPointer previousHandler; </li></ul></ul><ul><ul><li>previousHandler = signal(SIGABRT, SignalHandler); </li></ul></ul><ul><ul><li>abort(); </li></ul></ul><ul><ul><li>} </li></ul></ul>
  64. 64. Exceptions in C : Shortcomings <ul><li>Destructor-ignorant. </li></ul><ul><ul><li>Oblivious of C++ destructors. </li></ul></ul><ul><ul><li>abort() , exit() and longjmp() cannot release local objects during termination or stack unwind. </li></ul></ul><ul><ul><li>Resources leak. </li></ul></ul><ul><li>Obtrusive. </li></ul><ul><ul><li>Interrogating global objects or function -return values leads to code clutter. </li></ul></ul><ul><ul><li>Programmers &quot;forget&quot; error checks. </li></ul></ul>
  65. 65. Exceptions in C : Shortcomings <ul><li>Inflexible. </li></ul><ul><ul><li>Return value spoils normal function semantics </li></ul></ul><ul><ul><li>longjmp() &quot;throws&quot; only a single int. </li></ul></ul><ul><ul><li>errno and signal/raise manipulate a small set of values with coarse resolution. </li></ul></ul><ul><ul><li>abort() and exit() always terminate the program. </li></ul></ul><ul><ul><li>assert() works only in debug program versions. </li></ul></ul><ul><li>Non-native. </li></ul><ul><ul><li>Require library support outside the core language. </li></ul></ul>
  66. 66. SEH in Microsoft-C Standard Exception Handling – A Precursor to Exception Handling in C++
  67. 67. SEH in VC++ <ul><li>SEH – Structured Exception Handling </li></ul><ul><li>Exception Handling in Microsoft C / C++ </li></ul><ul><ul><li>Keywords </li></ul></ul><ul><ul><ul><li>__except </li></ul></ul></ul><ul><ul><ul><li>__finally </li></ul></ul></ul><ul><ul><ul><li>__leave </li></ul></ul></ul><ul><ul><ul><li>__try </li></ul></ul></ul><ul><ul><li>Supports both termination and resume semantics in recovery </li></ul></ul><ul><ul><li>Precursor to Exception Handling in C++ & Java </li></ul></ul>
  68. 68. SEH in VC++ <ul><li>Extended Constructs </li></ul>__try { ... } __except( filter-expression ) { ... } __try { ... } __finally { ... } __try { ... __leave; ... }
  69. 69. SEH in VC++ <ul><li>Example </li></ul><ul><ul><li>int filter(void) { </li></ul></ul><ul><ul><ul><li>/* Stage 4 */ </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>int main(void) { </li></ul></ul><ul><ul><ul><li>__try { </li></ul></ul></ul><ul><ul><ul><ul><li>if (some_error) /* Stage 1 */ </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>RaiseException(...); /* Stage 2 */ </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>/* Stage 5 of resuming exception */ </li></ul></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>__except(filter()) /* Stage 3 */ { </li></ul></ul></ul><ul><ul><ul><ul><li>/* Stage 5 of terminating exception */ </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>return 0; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul>
  70. 70. Exceptions in C++ Basic Notions
  71. 71. Exceptions in C++ : Expectations <ul><li>Separate </li></ul><ul><ul><li>Error-handling code from ordinary code </li></ul></ul><ul><ul><li>Raise Code from Handle Code </li></ul></ul><ul><li>Automatic Detection </li></ul><ul><li>Exception propagation allows a high level of reuse of exception handling code </li></ul><ul><li>Release local resources automatically </li></ul>
  72. 72. Exceptions in C++ : Example <ul><li>#include <iostream> </li></ul><ul><li>using namespace std; </li></ul><ul><li>int main () { </li></ul><ul><ul><li>try{ </li></ul></ul><ul><ul><li>... </li></ul></ul><ul><ul><li>throw20; // throw an exception </li></ul></ul><ul><ul><li>... </li></ul></ul><ul><ul><li>} catch(int e) { </li></ul></ul><ul><ul><li>cout << &quot;Exception No. &quot; << e << endl; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>return 0; </li></ul><ul><li>} </li></ul>
  73. 73. Exceptions in C++ : try–catch–throw <ul><li>Basic Mechanism </li></ul>void f() { A a; try { B b; g(); h(); } catch (UsrExcp& ex) { cout << ex.what(); } return; } <ul><ul><li>class UsrExcp: </li></ul></ul><ul><ul><li>public exceptions {} </li></ul></ul><ul><ul><li>void g() </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>A a; </li></ul></ul><ul><ul><li>UsrExcp ex(“From g()”); </li></ul></ul><ul><ul><li>throw ex; </li></ul></ul><ul><ul><li>return; </li></ul></ul><ul><ul><li>} </li></ul></ul>
  74. 74. try Block : Scope <ul><li>try block </li></ul><ul><ul><li>indicates areas in the program that might throw exceptions we want to handle immediately. </li></ul></ul><ul><li>function try block </li></ul><ul><ul><li>indicates that we want to detect exceptions in the entire body of a function. </li></ul></ul>void f() try { throw E(&quot;Exception thrown in f()&quot;); } catch (E& e) { cout << e.error << endl; }
  75. 75. try Block : Nested try Block <ul><li>Nesting try blocks is semantically equivalent to nested function calls each having a separate level of try block </li></ul><ul><li>A try block can be nested within a catch block. </li></ul>try { func1(); try { func2(); } catch (spec_err) { /* ... */ } func3(); } catch (type_err) { /* ... */ }
  76. 76. catch Block : Arguments <ul><li>Catch is the name of all handlers </li></ul><ul><ul><li>must immediately follow the try block </li></ul></ul><ul><ul><li>formal parameter of each handler must be unique </li></ul></ul><ul><ul><li>Formal parameter does not have to be a variable </li></ul></ul><ul><ul><li>Can be simply a type name to distinguish its handler from others </li></ul></ul><ul><ul><li>A variable transfers information to the handler </li></ul></ul><ul><ul><li>Catching an Exception is like a function being invoked. </li></ul></ul>
  77. 77. catch Block : Matching throw-catch <ul><li>Exact Match: </li></ul><ul><ul><li>The catch argument type matches the type of the thrown object. </li></ul></ul><ul><ul><ul><li>No implicit conversion is allowed. </li></ul></ul></ul><ul><li>Generalization / Specialization: </li></ul><ul><ul><li>The catch argument is a public base class of the thrown class object. </li></ul></ul><ul><li>Pointer: </li></ul><ul><ul><li>Pointer types – convertible by standard conversion. </li></ul></ul>
  78. 78. catch Block : Matching throw-catch <ul><li>NOTE: </li></ul><ul><ul><li>cv-qualification for catch needs to be as strong as the cv-qualification for throw </li></ul></ul><ul><ul><ul><li>If the type of the thrown object is const or volatile, the catch argument must also be a const or volatile for a match to occur. </li></ul></ul></ul><ul><ul><ul><li>However, a const, volatile, or reference type catch argument can match a non-constant, nonvolatile, or non-reference object type. </li></ul></ul></ul><ul><ul><li>A non-reference catch argument type matches a reference to an object of the same type. </li></ul></ul>
  79. 79. catch Block : Order of Catch <ul><li>In the order of appearance with matching. </li></ul><ul><li>Should the catch block of a base class precedes a catch block of a derived class: </li></ul><ul><ul><li>Compiler issues a warning and continues </li></ul></ul><ul><ul><li>Unreachable code (derived class handler) ignored. </li></ul></ul><ul><li>catch(...) block must be the last catch block because it catches all exceptions. </li></ul>
  80. 80. catch Block : Order of Match <ul><li>In case of no matching handler in the current scope, the search continues to find a matching handler in a dynamically surrounding try block. </li></ul><ul><ul><li>Stack Unwinds </li></ul></ul><ul><li>If eventually no handler is found, terminate() is called. </li></ul>
  81. 81. throw Expression : Semantics <ul><li>Indicate that program has encountered an exception. </li></ul><ul><li>E xpression is treated the same way as </li></ul><ul><ul><li>A function argument in a call or </li></ul></ul><ul><ul><li>the operand of a return statement. </li></ul></ul>
  82. 82. throw Expression : Semantics <ul><li>Exception Context </li></ul><ul><ul><li>class Exception {}; </li></ul></ul><ul><li>The Expression </li></ul><ul><ul><li>Generate an Exception object to throw. </li></ul></ul><ul><ul><ul><li>throw Exception(); </li></ul></ul></ul><ul><ul><li>Or, Copies an existing Exception object to throw. </li></ul></ul><ul><ul><ul><li>Exception ex; </li></ul></ul></ul><ul><ul><ul><li>… </li></ul></ul></ul><ul><ul><ul><li>throw ex; // Exception(ex); </li></ul></ul></ul><ul><li>Exception object is created on the Free Store. </li></ul>
  83. 83. (re) throw : Semantics <ul><li>Re-throw </li></ul><ul><ul><li>catch may pass on the exception after handling. </li></ul></ul><ul><ul><li>Re-throw is not same as throwing again! </li></ul></ul><ul><li>// Re-throw </li></ul><ul><li>try { ... } </li></ul><ul><li>catch (Exception& ex) { </li></ul><ul><li>// Handle and </li></ul><ul><li>... </li></ul><ul><li>// Pass-on </li></ul><ul><li>throw; </li></ul><ul><li>// No copy </li></ul><ul><ul><ul><li>// No Destruction </li></ul></ul></ul><ul><li>} </li></ul><ul><li>// Throws again </li></ul><ul><li>try { ... } </li></ul><ul><li>catch (Exception& ex) { </li></ul><ul><li>// Handle and </li></ul><ul><li>... </li></ul><ul><li>// Raise again </li></ul><ul><li>throw ex; </li></ul><ul><ul><ul><li>// ex copied </li></ul></ul></ul><ul><ul><ul><li>// ex destructed </li></ul></ul></ul><ul><li>} </li></ul>
  84. 84. throw Expression : Semantics <ul><li>For a UDT Expression: </li></ul><ul><ul><li>copy constructor and destructor must be accessible. </li></ul></ul><ul><li>The type of Expression cannot be </li></ul><ul><ul><li>An incomplete type, or </li></ul></ul><ul><ul><li>A pointer to an incomplete type, except </li></ul></ul><ul><ul><ul><li>void* </li></ul></ul></ul><ul><ul><ul><li>const void* </li></ul></ul></ul><ul><ul><ul><li>volatile void* </li></ul></ul></ul><ul><ul><ul><li>const volatile void* </li></ul></ul></ul>
  85. 85. Incomplete Type <ul><li>The void type </li></ul><ul><li>Arrays of unknown size </li></ul><ul><li>Arrays of elements that are of incomplete type </li></ul><ul><li>Structure, union, or enumerations that have no definition </li></ul><ul><li>Pointers to class types that are declared but not defined </li></ul><ul><li>Classes that are declared but not defined </li></ul>
  86. 86. Incomplete Type <ul><li>Except: </li></ul><ul><ul><li>If an array size is specified by [*], indicating a variable length array, the size is considered as having been specified, and the array type is then considered a complete type. </li></ul></ul><ul><li>Examples: </li></ul><ul><ul><li>void *incomplete_ptr; </li></ul></ul><ul><ul><li>struct dimension linear; </li></ul></ul><ul><ul><li>/* no previous definition of dimension */ </li></ul></ul>
  87. 87. Exceptions in C++ : Exception Lifetime <ul><li>[1] Incidence: </li></ul><ul><ul><li>The program or its library traps an error condition </li></ul></ul><ul><li>[2] Raise </li></ul><ul><ul><li>Throws an exception </li></ul></ul><ul><ul><li>Exception object created on the Free Store </li></ul></ul><ul><ul><ul><li>Constructor / Copy Constructor publicly needed </li></ul></ul></ul>
  88. 88. Exceptions in C++ : Exception Lifetime <ul><li>[3] Detection </li></ul><ul><ul><li>Execution stops at the point of the exception </li></ul></ul><ul><ul><li>Search for an exception handler begins. </li></ul></ul><ul><ul><li>Call stack is unwound till an exception declaration is found that is compatible with the exception object's static type </li></ul></ul>
  89. 89. Exceptions in C++ : Exception Lifetime <ul><li>[4] Handle </li></ul><ul><ul><li>The corresponding handler is entered </li></ul></ul><ul><li>[5] Recover </li></ul><ul><ul><li>Once the (catch) handler finishes, execution jumps to the point just beyond the enclosing try block. </li></ul></ul><ul><ul><li>Exception object is destructed </li></ul></ul><ul><ul><ul><li>Destructor is publicly needed </li></ul></ul></ul><ul><ul><li>Standard exceptions are always terminating. </li></ul></ul>
  90. 90. Exceptions in C++ : Advantages <ul><li>Destructor-savvy. </li></ul><ul><ul><li>Stack unwinds during a throw </li></ul></ul><ul><ul><li>Local-objects destructed in the proper order. </li></ul></ul><ul><li>Unobtrusive. </li></ul><ul><ul><li>Exceptions are caught implicitly and automatically. No clutter of error checks. </li></ul></ul><ul><li>Precise. </li></ul><ul><ul><li>Nearly any object can be thrown & caught. </li></ul></ul><ul><ul><li>Programmer controls exception semantics. </li></ul></ul>
  91. 91. Exceptions in C++ : Advantages <ul><li>Scalable. </li></ul><ul><ul><li>Each function can have multiple try blocks. </li></ul></ul><ul><ul><li>Each try block can have a single handler or a group of handlers. </li></ul></ul><ul><ul><li>Each handler can catch a single type, a group of types, or all types. </li></ul></ul>
  92. 92. Exceptions in C++ : Advantages <ul><li>Fault -tolerant. </li></ul><ul><ul><li>Functions can specify the exception types to throw; handlers can specify the exception types to catch. </li></ul></ul><ul><ul><li>Violation behavior of these specifications is predictable and user-configurable. </li></ul></ul><ul><li>Native. </li></ul><ul><ul><li>EH is part of the C++ language. </li></ul></ul><ul><li>Standard. </li></ul><ul><ul><li>EH is available in all standard C++ compilers. </li></ul></ul>
  93. 93. Exception Specifications in C++ Notions
  94. 94. Exception Specification : Notion <ul><li>Limits a function to throwing only a specified list of exceptions. </li></ul><ul><li>Given at the signature of the function. </li></ul><ul><li>Acts as a guarantee to the function's caller. </li></ul>
  95. 95. Exception Specification : Rules <ul><li>Allow specified exceptions (and its specialization). </li></ul><ul><ul><li>void *operator new (size_t) throw(bad_alloc); </li></ul></ul><ul><ul><li>// Will throw bad_alloc or its specialization </li></ul></ul><ul><li>No / Wildcard specification allows all exceptions. </li></ul><ul><ul><li>void *operator new (size_t); </li></ul></ul><ul><ul><li>// can throw bad_alloc – This is in standard </li></ul></ul><ul><ul><li>void *operator new (size_t) throw(...); </li></ul></ul><ul><ul><li>// can throw bad_alloc – This is not in standard </li></ul></ul><ul><li>Empty specification does not allow any exceptions. </li></ul><ul><ul><li>void *operator new (size_t) throw(); </li></ul></ul><ul><ul><li>// does not throw – nothrow version </li></ul></ul>
  96. 96. Exception Specification : Rules <ul><li>Multiple Specifications are allowed. For </li></ul><ul><ul><li>void translate() </li></ul></ul><ul><ul><li>throw (unknown_word, bad_grammar) </li></ul></ul><ul><ul><li>translate() will only throw exception of </li></ul></ul><ul><ul><ul><li>type unknown_word or </li></ul></ul></ul><ul><ul><ul><li>type bad_grammar or </li></ul></ul></ul><ul><ul><ul><li>any type derived from unknown_word or </li></ul></ul></ul><ul><ul><ul><li>any type derived from bad_grammar . </li></ul></ul></ul><ul><li>Reasoning about Exception Specification follows rules similar to cv-qualification </li></ul>
  97. 97. Exception Specification : Details <ul><li>An exception specification may only appear at the end of a function declarator of a </li></ul><ul><ul><li>function, </li></ul></ul><ul><ul><li>pointer / reference to function, </li></ul></ul><ul><ul><li>pointer to member function declaration / definition. </li></ul></ul><ul><li>An exception specification is not part of a function's type. </li></ul><ul><ul><li>Functions cannot be overloaded on Specification </li></ul></ul><ul><ul><li>Specification cannot appear in a typedef </li></ul></ul>
  98. 98. Exception Specification : Examples <ul><li>void f() throw(int); </li></ul><ul><li>void (*g)() throw(int); </li></ul><ul><li>void h(void i() throw(int)); </li></ul><ul><li>// typedef int (*j)() throw(int); </li></ul><ul><li>// This is an error. </li></ul>
  99. 99. Exception Specification : Examples <ul><li>It is okay to throw A() – as specified. </li></ul><ul><li>It is okay to throw B() – specialization from A. </li></ul><ul><li>It is a violation to throw C() </li></ul><ul><li>class A { }; </li></ul><ul><li>class B : public A { }; </li></ul><ul><li>class C { }; </li></ul><ul><li>void f(int i) throw (A) { </li></ul><ul><ul><li>switch (i) { </li></ul></ul><ul><ul><ul><li>case 0: throw A(); </li></ul></ul></ul><ul><ul><ul><li>case 1: throw B(); </li></ul></ul></ul><ul><ul><ul><li>default: throw C(); </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>Will Violate
  100. 100. Exception Specification : Examples <ul><li>It is okay to throw pA – as specified. </li></ul><ul><li>It is okay to throw pB – B* specialized from A*. </li></ul><ul><li>It is a violation to throw pC – C* is unrelated. </li></ul><ul><li>void g(int i) throw (A*) { </li></ul><ul><li>A* pA = new A(); </li></ul><ul><li>B* pB = new B(); </li></ul><ul><li>C* pC = new C(); </li></ul><ul><ul><li>switch (i) { </li></ul></ul><ul><ul><ul><li>case 0: throw pA; </li></ul></ul></ul><ul><ul><ul><li>case 1: throw pB; </li></ul></ul></ul><ul><ul><ul><li>default: throw pC; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>Will Violate
  101. 101. Exception Specification : Violation Handling <ul><li>For specification violation, </li></ul><ul><ul><li>Compiler calls </li></ul></ul><ul><ul><ul><li>void unexpected(); // from Standard Library </li></ul></ul></ul><ul><ul><li>That in turn calls </li></ul></ul><ul><ul><ul><li>void terminate(); // from Standard Library </li></ul></ul></ul><ul><ul><li>Which by default calls </li></ul></ul><ul><ul><ul><li>abort() </li></ul></ul></ul><ul><li>If bad_exception is listed in the exception specification, </li></ul><ul><ul><li>unexpected() will throw an implementation-defined object of this class instead. </li></ul></ul>
  102. 102. Exception Specification : Violation Handling <ul><li>For specification violation, compiler calls (from Standard Library) </li></ul><ul><ul><li>void unexpected(); </li></ul></ul><ul><ul><li>unexpected() may throw bad_exception; </li></ul></ul><ul><li>User can register her version of unexpected() by (Standard Library) </li></ul><ul><ul><li>unexpected_handler set_unexpected(unexpected_handler) throw(); </li></ul></ul>
  103. 103. Exception Specification : Polymorphism Restrictions <ul><li>A overriding virtual function can only throw exceptions specified by the virtual function in the base . </li></ul>class A { public: virtual void f() throw(int, char) ; }; class B : public A { public: void f() throw(int) { } }; /* The following is not allowed. class C : public A { public: void f() throw(...) { } }; class D : public A { public: void f() throw(int, char, double) { } }; */
  104. 104. Exception Specification : Function Pointer Restrictions <ul><li>f = h is allowed </li></ul><ul><ul><li>f can throw any kind of exception. </li></ul></ul><ul><li>h = g is not allowed </li></ul><ul><ul><li>h can only throw objects of type int, while g can throw any kind of exception. </li></ul></ul><ul><li>void (*f)(); </li></ul><ul><li>void (*g)(); </li></ul><ul><li>void (*h)() throw (int); </li></ul><ul><li>void i() { </li></ul><ul><ul><li>f = h; </li></ul></ul><ul><ul><li>// h = g; This is an error. </li></ul></ul><ul><li>} </li></ul>
  105. 105. Exception Specification : Union of Specification <ul><li>C::C() can throw exceptions of type int or char. </li></ul><ul><li>C::C(C&) can throw any kind of exception. </li></ul><ul><li>C::~C() cannot throw any exceptions. </li></ul><ul><li>class A { public: </li></ul><ul><ul><li>A() throw (int); </li></ul></ul><ul><ul><li>A(const A&) throw (float); </li></ul></ul><ul><ul><li>~A() throw(); }; </li></ul></ul><ul><li>class B { public: </li></ul><ul><ul><li>B() throw (char); </li></ul></ul><ul><ul><li>B(const A&); </li></ul></ul><ul><ul><li>~B() throw(); }; </li></ul></ul><ul><li>class C : public B, </li></ul><ul><li>public A { }; </li></ul>// Special functions // Implicitly declared // Implicitly specified C::C() throw (int, char); C::C(const C&); C::~C() throw();
  106. 106. Exception Specification : Compiler Support <ul><li>Not all compilers Support Exception Specification </li></ul><ul><li>For example, Visual C++ departs from the ANSI Standard in its exception specifications behavior. </li></ul><ul><ul><li>throw(): </li></ul></ul><ul><ul><ul><li>The function does not throw an exception. </li></ul></ul></ul><ul><ul><ul><li>It is the equivalent to using __declspec(nothrow). </li></ul></ul></ul><ul><ul><li>throw(...): </li></ul></ul><ul><ul><ul><li>The function can throw an exception. </li></ul></ul></ul><ul><ul><li>throw( type ): </li></ul></ul><ul><ul><ul><li>The function can throw an exception of type type . However, in Visual C++ .NET, this is interpreted as throw(...) . </li></ul></ul></ul>
  107. 107. Exception Specification : Compiler Workaround is equivalent to void SomeFunction() throw (E1, E2) { ... } void SomeFunction() try { ... } catch (E1) { throw; } catch (E2) { throw; } catch (...) { std::unexpected(); }
  108. 108. Standard Exceptions in C++ Classes, Types and Functions
  109. 109. Standard C++ Exception-Object Types
  110. 110. Standard Exceptions : Classes <ul><li>Exceptions for Language Support </li></ul><ul><ul><li>Operators & Mechanisms </li></ul></ul><ul><ul><ul><li>operator new </li></ul></ul></ul><ul><ul><ul><ul><li>bad_alloc: On allocation failure </li></ul></ul></ul></ul><ul><ul><ul><li>operator dynamic_cast </li></ul></ul></ul><ul><ul><ul><ul><li>bad_cast: On failure to resolve a reference </li></ul></ul></ul></ul><ul><ul><ul><li>operator typeid </li></ul></ul></ul><ul><ul><ul><ul><li>bad_typeid: On NULL pointer </li></ul></ul></ul></ul><ul><ul><ul><li>unexpected() functions </li></ul></ul></ul><ul><ul><ul><ul><li>bad_exception: On mismatched specification </li></ul></ul></ul></ul>
  111. 111. Standard Exceptions : Classes <ul><li>Exception Classes for Standard Library </li></ul><ul><ul><li>logic_errors </li></ul></ul><ul><ul><ul><li>Internal program bugs </li></ul></ul></ul><ul><ul><ul><li>Theoretically preventable </li></ul></ul></ul><ul><ul><ul><li>Exceptions are: </li></ul></ul></ul><ul><ul><ul><ul><li>invalid_argument </li></ul></ul></ul></ul><ul><ul><ul><ul><li>length_error </li></ul></ul></ul></ul><ul><ul><ul><ul><li>out_of_range </li></ul></ul></ul></ul><ul><ul><ul><ul><li>domain_error </li></ul></ul></ul></ul><ul><ul><ul><ul><li>ios_base::failure: On error or end-of-file by stream objects </li></ul></ul></ul></ul>
  112. 112. Standard Exceptions : Classes <ul><li>Exception for Errors outside the Scope of a Program </li></ul><ul><ul><li>runtime_errors </li></ul></ul><ul><ul><ul><li>External to program's control </li></ul></ul></ul><ul><ul><ul><li>Difficult to predict. </li></ul></ul></ul><ul><ul><ul><li>Exceptions are: </li></ul></ul></ul><ul><ul><ul><ul><li>range_error </li></ul></ul></ul></ul><ul><ul><ul><ul><li>overflow_error </li></ul></ul></ul></ul><ul><ul><ul><ul><li>underflow_error </li></ul></ul></ul></ul>
  113. 113. Standard Exceptions : Headers <ul><li><exception> </li></ul><ul><li>namespace std </li></ul><ul><li>{ </li></ul><ul><ul><li>// classes </li></ul></ul><ul><ul><li>class bad_exception; </li></ul></ul><ul><ul><li>class exception; </li></ul></ul><ul><li>} </li></ul>
  114. 114. Standard Exceptions : Headers <ul><li><stdexcept> </li></ul><ul><li>namespace std </li></ul><ul><li>{ </li></ul><ul><ul><li>class logic_error; // : public exception </li></ul></ul><ul><ul><ul><li>class domain_error; // : public logic_error </li></ul></ul></ul><ul><ul><ul><li>class invalid_argument; // : public logic_error </li></ul></ul></ul><ul><ul><ul><li>class length_error; // : public logic_error </li></ul></ul></ul><ul><ul><ul><li>class out_of_range; // : public logic_error </li></ul></ul></ul><ul><ul><li>class runtime_error; // : public exception </li></ul></ul><ul><ul><ul><li>class range_error; // : public runtime_error </li></ul></ul></ul><ul><ul><ul><li>class overflow_error; // : public runtime_error </li></ul></ul></ul><ul><ul><ul><li>class underflow_error; // : public runtime_error </li></ul></ul></ul><ul><li>} </li></ul>
  115. 115. Standard Exceptions : Types <ul><li>typedef void (*terminate_handler)(); </li></ul><ul><ul><li>Function pointer type for a program termination handler </li></ul></ul><ul><li>typedef void (*unexpected_handler)(); </li></ul><ul><ul><li>Function pointer type for an unexpected exception handler </li></ul></ul>
  116. 116. Standard Exceptions : Functions <ul><li>void terminate() </li></ul><ul><ul><li>Called when an exception is raised while a previous exceptional condition is still being handled (reentrancy). </li></ul></ul><ul><li>void unexpected() </li></ul><ul><ul><li>Called when a function throws an exception it promised not to throw, in violation of its exception specification. </li></ul></ul><ul><ul><li>May be replaced by a bad_exception object during the stack unwind. </li></ul></ul>
  117. 117. Standard Exceptions : Functions <ul><li>bool uncaught_exception() </li></ul><ul><ul><li>returns true if an exception has been thrown but not caught, and false otherwise. </li></ul></ul>
  118. 118. Standard Exceptions : Functions <ul><li>terminate_handler set_terminate(terminate_handler) throw(); </li></ul><ul><ul><li>Registers a user-defined termination handler </li></ul></ul><ul><li>unexpected_handler set_unexpected(unexpected_handler) throw(); </li></ul><ul><ul><li>Registers a user-defined unexpected exception handler </li></ul></ul>
  119. 119. Standard Exceptions : Headers <ul><li><exception> </li></ul><ul><li>namespace std </li></ul><ul><li>{ </li></ul><ul><ul><li>// types </li></ul></ul><ul><ul><li>typedef void (*terminate_handler)(); </li></ul></ul><ul><ul><li>typedef void (*unexpected_handler)(); </li></ul></ul><ul><ul><li>// functions </li></ul></ul><ul><ul><li>terminate_handler </li></ul></ul><ul><ul><li>set_terminate(terminate_handler) throw(); </li></ul></ul><ul><ul><li>unexpected_handler </li></ul></ul><ul><ul><li>set_unexpected(unexpected_handler) throw(); </li></ul></ul><ul><ul><li>void terminate(); </li></ul></ul><ul><ul><li>void unexpected(); </li></ul></ul><ul><ul><li>bool uncaught_exception(); </li></ul></ul><ul><li>} </li></ul>
  120. 120. Handling Exceptions in C & C++ References & Credits
  121. 121. 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 </li></ul></ul><ul><li>A Pragmatic Look at Exception Specifications </li></ul><ul><ul><li> </li></ul></ul>
  122. 122. Credits / Acknowledgements
  123. 123. Thank You