1 / 18

Exceptions

This article provides an introduction to exception handling in programming, including its definition, motivation, and syntax. It explains the need for exception handling and how to use try-catch blocks to handle exceptions. It also covers topics such as throwing objects, stack unwinding, re-throwing, catch-all clauses, and exception specifications.

odommary
Download Presentation

Exceptions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Exceptions

  2. Introduction to Exception Handling • Definition: An exception is any unusual event, either erroneous or not, detectable by either hardware or software, that may require special processing • Without exception handling • When an exception occurs, control goes to the operating system, where typically • an error message is displayed • the program is terminated • With exception handling • Programs are allowed to trap exceptions • There is a possibility to fix the problem and continuing execution

  3. Possible Naïve Solutions • Exit the Program • Isn’t it too strong • OS already does the same • Return Error Code • Need to check the return code for every call • Raise a Flag • Need to check the flag after every operation • Call a Special Code to Correct the Error • But when shall we call it?

  4. Motivation • A mechanism which allows two components to survive runtime program anomaly • Encountering such an anomaly (division by zero, access to an array outside its bound, etc.), may need an immediate handling • The handling may reside in a different component, which we need to communicate • The encountering components throws an exception • The handling code, catches the exception, and handles it accordingly

  5. Example • Lets consider class stack const int MAX_ELEM=10; template <typename T, int size=MAX_ELEM> class Stack { T m_arr[size]; int m_index; public: Stack() : m_index(0) {} void Push(T elemP) { m_arr[m_index] = elemP; m_index++; } T& Pop() { m_index--; return m_arr[m_index]; } int Index() const { return m_index; } };

  6. Exception Handling Syntax • Exception Handlers try { -- code that is expected to raise an exception } catch (formal parameter) { -- handler code } ...

  7. Class Anomalies • What happens if we pop() an empty stack? • What happens if we push() on a full stack? • We decide that these situations need to be handled in a special manner, since they are anomalies of the class behavior. • First we define classes of exceptions which may be thrown • Upon anomaly detection, we will throw an exception class popOnEmpty { /* … */ } class pushOnFull { /* … */ }

  8. Example • Our code would now change • No need to examine the returned value for checking for success. … void Push(T elemP) { if (m_index>=size) throw pushOnFull(); // an object is throws m_arr[m_index] = elemP; m_index++; } T& Pop() { if (m_index<=0) throw popOnEmpty(); // an object is thrown m_index--; return m_arr[m_index]; } … };

  9. Try…Catch Blocks • Wrap the code which needs to be “exception sensitive”, and react to raised exceptions, in a try {…} catch {…} blocks • The client’s code look now as following int main() { try{ Stack<int> si; si.Pop(); si.Push(5); si.Pop(); } catch (popOnEmpty) { cout << "stack is empty !!" << endl; } };

  10. Try…Catch Blocks • When exception is thrown, execution resumes in the “closest” catch clause handling the exception. • If no catch clause exists capable of handling the exception, program execution resumes at the terminate() function. • Variables declared within the try block cannot be referred to at the catch clause, since they are local to the block. int main() { try{ Stack<int> si; si.Pop(); si.Push(5); si.Pop(); } catch (popOnEmpty) { cout << "stack is empty !!" << endl; } cout << “Execution resumes here” << endl; }; Execution does Not resume here Type declaration

  11. Throwing Objects • Why throw an object? • Additional data encapsulated • An object is created upon invoking the throw statement • Can be created with additional data, passed to Ctor • Object is destroyed after the catch clause ends

  12. Stack Unwinding • Up the chain of nested function calls, a suitable catch clause is searched for • Upon functions and compound statements exit, stack is being unwound • Lifetime of local variables ends • Destructors are called • If no handler is supplied, terminate() is called • Since exception is a situation, where the program cannot continue execution in a normal manner • By default terminate() calls abort() • Similar to function call behavior • But information to set up a function call is not available at compile time, run-time support is needed

  13. Re-throwing and Catch All • After some corrective action, a catch clause may throw an exception to be further handled, passing the exception to another catch clause, by throw. • General exception handling can be specified catch(…) { // place code here } • If specified with combination, must be specified last, since evaluation is evaluated in turn.

  14. Exception Specification • Function interface need to be as precise as possible, it is the contract between several codes • Client code may need to prepare for specific handling • Best is to provide exception specification with the method declaration • This will help the compiler to check consistency, to check that no other exceptions are thrown • It follows the function parameter list

  15. Exception Specification … void Push(T elemP) throw(pushOnFull) { if (m_index>=size) throw pushOnFull(); // an object is throws m_arr[m_index] = elemP; m_index++; } T& Pop() throw(popOnEmpty) { if (m_index<=0) throw popOnEmpty(); // an object is thrown m_index--; return m_arr[m_index]; } … };

  16. Nesting try Blocks • Exceptions are always handled by closest matching handler try { try { throw 5; } catch (int x) { cout << x << endl; // exception will be caught here } } catch (int x) { cout << x-5 << endl; }

  17. Exceptions from Function Calls • No different from nested try blocks • Auto variables on stack are destroyed • Exception jumps to nearest handler • Allows exception handlers to be implemented far away from where the problem was • May requires a knowledge of the issue packaged in exception object for appropriate handling

  18. Exception Hierarchies • Class types representing exceptions may be organized into groups or hierarchies Class Excp {} Class stackExcp : public Excp {} Class popOnEmpty : public stackExcp {} Class pushOnFull : public stackExcp {} • Throwing an exception of type popOnEmpty may be caught by a handler expecting its base • Therefore order should be handling more concrete types, and then handling more generic types • Since handling is evaluated in order of specification, “first match” • Ctors and Dtors are called in order like before

More Related