COMP 345 Advanced Program Design with C 1

  • Slides: 16
Download presentation
COMP 345 - Advanced Program Design with C++ 1 Click to edit Master title

COMP 345 - Advanced Program Design with C++ 1 Click to edit Master title style ADVANCED PROGRAM DESIGN WITH C++ Part 10: Exception handling Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 2 Exception handling: robustness and fault

COMP 345 - Advanced Program Design with C++ 2 Exception handling: robustness and fault tolerance • Programs are meant to work correctly within their specifications. • However, a program might be faced with unforeseen circumstances that are outside of its specifications. • Unforeseen situations may come: • Externally from the environment of the program • When a user or software client tries to use the software outside of its specified usage characteristics. • When the program tries to use another piece of software and is faced with unforeseen behavior. • Internally from its own execution • When the program misbehaves due to an internal logical error and/or being in an inconsistent state. • A robust program should be able to handle all kinds of circumstances, normal or faulty, whether the faults are coming from the exterior or are a result of its own internal faults. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 3 Exception handling: introduction • Exception

COMP 345 - Advanced Program Design with C++ 3 Exception handling: introduction • Exception handling is a mechanism that allows two separately developed program components to communicate when a program anomaly is encountered during the execution of the program. • Such communication upon erroneous behavior has been long part of programming practice in the form of error codes and error handling. • In error handling, functions produce special error codes in case of malfunction and finish execution normally. • It is then assumed that any function that might be affected by the error will use the error code and react by handling the error i. e. to continue normal execution despite the error. • In this view, normal execution is blended with the system’s reaction to abnormal circumstances. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 4 Exception handling: example C programs

COMP 345 - Advanced Program Design with C++ 4 Exception handling: example C programs with error handling #include <stdio. h> #include <errno. h> #include <string. h> extern int errno; int main() { FILE * pf; int errnum; pf = fopen("unexist. txt", "rb"); if (pf == NULL) { errnum = errno; fprintf(stderr, "Value of errno: %dn", errno); perror("Error printed by perror"); fprintf(stderr, "Error opening file: %sn", strerror(errnum)); } else { fclose(pf); #include <stdio. h> } #include <stdlib. h> return 0; } main() { int dividend = 20; int divisor = 5; int quotient; if (divisor == 0){ fprintf(stderr, "Division by zero! Exiting. . . n"); exit(EXIT_FAILURE); } quotient = dividend / divisor; fprintf(stderr, "Value of quotient : %dn", quotient); exit(EXIT_SUCCESS); } Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 5 Exception handling: introduction • Error

COMP 345 - Advanced Program Design with C++ 5 Exception handling: introduction • Error handling introduces confusion as it does not enable to separate normal behavior from error-handling behavior. • To be more structured, functions should be first programmed according to the specifications of their normal behavior, and clearly separate code should be provided for abnormal cases, i. e. cases outside of the function’s specifications of normal behavior. • The first programming language to provide a primitive concept of exception handling was LISP in the early 1960. PL/1 later extended the concept in the early 1970 s. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 6 Exception handling: introduction • An

COMP 345 - Advanced Program Design with C++ 6 Exception handling: introduction • An exception is a data structure that is generated when an erroneous condition is met, that contains information about the nature and context of this erroneous condition. • Exceptions are processed by an exception handling mechanism that only takes effect when an exception has been identified. • The exception handling mechanism will then take over the normal execution mechanism until the exception is resolved. • If the exception can be properly resolved, normal execution is resumed. • If the exception cannot be resolved, the program execution is terminated. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 7 Exception handling: try-throw-catch • Syntactically,

COMP 345 - Advanced Program Design with C++ 7 Exception handling: try-throw-catch • Syntactically, handling exceptions in C++ is made through the try- throw-catch keyword trio, which is highly similar to what is used in Java. The try block • The try block contains a part of the code for the normal execution of the program. • It is called a try block because it tries to execute the normal execution behavior, but where something is likely to be subject to exceptionally erroneous behavior. Code that will/should not throw any exception try { Code. That. May. Throw. An. Exception } Code that will/should not throw any exception Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 8 Exception handling: try-throw-catch The throw

COMP 345 - Advanced Program Design with C++ 8 Exception handling: try-throw-catch The throw statement • Whenever a piece of code identifies an exceptionally wrong situation, it can create an exception and trigger the exception handling mechanism by using a throw statement: throw value throw new Exception. Class. Name(Possibly. Some. Arguments); • When an exception is thrown, the normal execution of the surrounding try block is stopped and the exception handling mechanism takes over the execution of the program. • Normally, the flow of control is transferred by the exception handling mechanism to another portion of code known as a catch block. • The value thrown is the argument to the throw operator, and can be any value (possibly an instance of some exception class). Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 9 Exception handling: try-throw-catch • A

COMP 345 - Advanced Program Design with C++ 9 Exception handling: try-throw-catch • A throw statement is similar to a method call: throw new Class. Name(“Some Descriptive String”); • In the above example, an object of class Class. Name is created using a string as its argument (assuming that it has such a constructor defined) and used as an exception object. • Unlike Java, C++ can use any value as an exception, and classes used to instantiate exceptions do not need to be subclasses of the standard exception class. • The throw statement has the effect of temporarily halting the normal execution of the program and handing it over to the exception handling mechanism. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 10 Exception handling: try-throw-catch The catch

COMP 345 - Advanced Program Design with C++ 10 Exception handling: try-throw-catch The catch block • When an exception is thrown and the exception handling mechanism takes over, it tries to find a corresponding catch block to handle the exception. • A catch block has at most one parameter. • The exception object thrown is passed to the catch block using a similar mechanism as for a function call’s parameter passing. • The type of the catch block’s exception object parameter determines what kind of exception a catch block is meant to handle. • The execution of the catch block is called catching the exception, or handling the exception. catch(Exception e) { Exception. Handling. Code } Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 11 Exception handling: try-throw-catch • Any

COMP 345 - Advanced Program Design with C++ 11 Exception handling: try-throw-catch • Any catch block is attached to a specific try block. • A catch block is an exception handler that is meant to handle some exception thrown in the try block it is attached to. • The type of exception it is meant to handle is specified by its parameter type. • A single try block can be attached to as many catch blocks as there are different kinds of exceptions potentially thrown in the try block’s code. • A catch block mean to catch all exceptions is signified using an ellipse (…) as a parameter. // Code before try/catch block try { // Code that potentially throws some exception(s) } catch (Exception. Type 1 e){ // Exception handling code for Exception. Type 1 } catch (Exception. Type 2 e){ // Exception handling code for Exception. Type 1 } catch (. . . ){ // Exception handling code for any other type of // exception not handled by the preceding catch blocks } // Code after try/catch block Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 12 Exception handling: try-throw-catch • When

COMP 345 - Advanced Program Design with C++ 12 Exception handling: try-throw-catch • When a try block is executed, three things can happen: 1. No exception is thrown in the try block • The code in the try block is executed to the end of the block. • The catch blocks are skipped. • The execution continues with the code placed after the catch block. 2. An exception is thrown in the try block and caught in a catch block • The rest of the code in the try block is skipped. • Control is transferred to a following catch block. • The thrown object is passed to the catch block using parameter passing. • The code in the catch block is executed. • Normal execution resumes using the code that follows all catch blocks. 3. An exception is thrown in the try block and there is no corresponding catch block to handle the exception • The rest of the code in the try block is skipped. • The function throws the exception to its calling function. • The calling function either catches the exception using a catch block, or throws the exception to its calling function. • If all the called functions fail to catch the exception, the exception will eventually be thrown all the way to the main function. • If the main function cannot catch the exception, the program ends, itself throwing the exception. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 13 Exception handling: stack unwinding •

COMP 345 - Advanced Program Design with C++ 13 Exception handling: stack unwinding • Once the exception handling mechanism takes control as a throw statement is executed, control moves from the throw statement to the first catch statement that can handle thrown type. • Once the control goes to the catch block handler (after parameter passing), a process known as stack unwinding is used to delete all the automatically allocated local variables that were used between the execution site where the exception was thrown and the execution site where the exception is caught. Concordia University void g(){ // to be deleted first during stack unwinding // including parameters passed as value throw std: : exception(); } void f(){ // to be deleted second during stack unwinding // including parameters passed as value g(); } int main(){ // not to be deleted during stack unwinding try { // to be deleted third during stack unwinding f(); } catch (. . . ){ } // resume here after handling } Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 14 Exception handling: stack unwinding #include

COMP 345 - Advanced Program Design with C++ 14 Exception handling: stack unwinding #include <string> #include <iostream> using namespace std; class My. Exception{}; class Dummy { public: Dummy(string s) : dummy. Name(s) { cout << "Created Dummy: " << dummy. Name << endl; } Dummy(const Dummy& other) : dummy. Name(other. dummy. Name){ cout << "Copy created Dummy: " << dummy. Name << endl; } ~Dummy(){ cout << "Destroyed Dummy: " << dummy. Name << endl; } string dummy. Name; }; int main() { cout << "Entering main" << endl; try { Dummy d("dummy_main"); // this will eventually throw f. A(d); } catch (My. Exception& e){ cout << "Caught an exception of type: " << typeid(e). name() << endl; } cout << "Exiting main. " << endl; char c; cin >> c; } Concordia University void f. C(Dummy d){ // copy constructor called for parameter passing cout << "Entering Function f. C" << endl; d. dummy. Name = "dummy_f. C"; // throw here throw My. Exception(); cout << "Exiting Function f. C" << endl; } void f. B(Dummy& d){ cout << "Entering Function f. B" << endl; d. dummy. Name = "dummy_f. B"; f. C(d); cout << "Exiting Function f. B" << endl; } void f. A(Dummy& d){ cout << "Entering Function f. A" << endl; Dummy stack. Dummy("Dummy on Stack"); // not exception safe // its delete is after exception being thrown Dummy* heap. Dummy = new Dummy("Dummy on Heap"); d. dummy. Name = "dummy_f. A"; // this will eventually throw f. B(d); delete heap. Dummy; cout << "Exiting Function f. A" << endl; } Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 15 Exception handling: stack unwinding •

COMP 345 - Advanced Program Design with C++ 15 Exception handling: stack unwinding • If exceptions are thrown in constructors, only the parts of the object that were yet fully constructed are destructed during stack unwinding. char class. To. Throw; class D { public: D(){ cout << "Constructor D()" << endl; if (class. To. Throw == 'D') throw class. To. Throw; } ~D(){ cout << "Destructor ~D()" << endl; } }; class C { public: C(){ cout << "Constructor C()" << endl; if (class. To. Throw == 'C') throw class. To. Throw; } ~C(){ cout << "Destructor ~C()" << endl; } }; class B { public: B(){ cout << "Constructor B()" << endl; if (class. To. Throw == 'B') throw class. To. Throw; } ~B(){ cout << "Destructor ~B()" << endl; } }; Concordia University class A : public B { public: C m. C 1; D m. D 2; A() { cout << "Constructor A()" << endl; if (class. To. Throw == 'A') throw class. To. Throw; } ~A(){ cout << "Destructor ~A()" << endl; } }; int main(){ while (true){ cout << "Enter a class name : "; cin >> class. To. Throw; try{ A* a = new A(); delete a; } catch (char c){ cout << "catching " << c << endl; } } system("PAUSE"); return EXIT_SUCCESS; } Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014

COMP 345 - Advanced Program Design with C++ 16 References • Andrew Koenig and

COMP 345 - Advanced Program Design with C++ 16 References • Andrew Koenig and Bjarne Stroustrup. 1993. Exception handling for C++. In The • • evolution of C++, Jim Waldo (Ed. ). MIT Press, Cambridge, MA, USA 137 -171. Goodenough, John B. Structured exception handling. Proceedings of the 2 nd ACM SIGACT-SIGPLAN symposium on Principles of programming languages POPL '75. pp. 204– 224. doi: 10. 1145/512976. 512997 tutorialspoint. com. C++ Exception Handling. tutorialspoint. com. C – Error Handling. informit. com. Stanley B. Lippman, Josée La. Joie, Exception Handling in C++. Microsoft Developer Network. C++ Exception Handling. Microsoft Developer Network. Exceptions and Stack Unwinding in C++. Wikibooks. C++ Programming, C++ Programming/Exception Handling. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2014