COMP 345 Advanced Program Design with C 1

  • Slides: 29
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 -2019

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

COMP 345 - Advanced Program Design with C++ 2 Exception handling: introduction • 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, foreseen or unforeseen, whether they are coming from the exterior or are a result of its own faults. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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. 1. 2. The code for the normal program execution in normal situations (i. e. the regular code). The code for program execution after encountering an abnormal situation. • 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 set or return special error codes in case of malfunction and finish execution normally. • It is then assumed that any function that might be affected will use the error code and react by handling the error i. e. to continue normal execution despite the error. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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> //system error numbers #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); // C Library function perror() perror("Error printed by perror"); // C Library function strerror() fprintf(stderr, "Error opening file: %sn", strerror(errnum)); } else { fclose(pf); } #include <stdio. h> return 0; #include <stdlib. h> } 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 -2019

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

COMP 345 - Advanced Program Design with C++ 5 Exception handling: introduction • However, 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 separated code should be provided for abnormal cases, i. e. cases outside of the function’s specifications of normal behavior. • This is what C++ exception handling is aiming to achieve. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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

COMP 345 - Advanced Program Design with C++ 6 Exception handling: introduction • The first programming language to provide the early concept of exception handling was LISP in the early 1960. PL/1 later extended the concept in the early 1970 s. • 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 handling 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 -2019

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 of the try-throw-catch keyword trio, which is highly similar to what is used in Java. • 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. If the code outside if a try throws an exception, the function halts and throws the exception to the calling function. try { Code that may throw an exception which is handled locally } If the code outside if a try throws an exception, the function halts and throws the exception to the calling function. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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

COMP 345 - Advanced Program Design with C++ 8 Exception handling: try-throw-catch • 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 Or more specifically 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. • In C++, 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 -2019

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 function call that takes an object as a parameter, then identifies it as an exception to be handled: 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 -2019

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

COMP 345 - Advanced Program Design with C++ 10 Exception handling: try-throw-catch • When an exception is thrown and the exception handling mechanism takes over, it tries to find a corresponding catch block to handle the exception. catch(Exception e) { Exception. Handling. Code } • 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. • A catch block is often called an exception handler. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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 meant to catch all exceptions is signified using an ellipse (…) as a parameter. 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 } Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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, in which case the rest of the code in the function is skipped and stack unwinding is applied on this function’s stack frame. A corresponding catch block is looked for in every function down the function call stack. • 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 -2019

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 to the first catch statement that can handle thrown type. • Once the control goes to the catch handler, 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. • Stack unwinding does not delete heap-allocated values. • Hence, heap-allocated variables in code before the location where the exception is thrown outside of a catch will lead to a memory leak. • Solution: avoid them or create a try-catch to allocate/deallocate them. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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

COMP 345 - Advanced Program Design with C++ 14 Exception handling: stack unwinding: example string which. To. Fail; class My. Class { public: string name; My. Class(const string new. Name) : name(new. Name) { cout << "in My. Class constructor: " << name << endl; }; ~My. Class() { cout << "In My. Class destructor: " << name << endl; } }; void g() { // to be deleted first during stack unwinding // including parameters passed as value My. Class mc 4("mc 4"); if (which. To. Fail == "g") throw std: : exception(); My. Class mc 5("mc 5"); } void f() { // to be deleted second during stack unwinding // including parameters passed as value My. Class mc 2("mc 2"); if (which. To. Fail == "f") throw std: : exception(); g(); My. Class mc 3("mc 3"); } int main() { cin >> which. To. Fail; // not to be deleted during stack unwinding My. Class mc 1("mc 1"); try { // to be deleted third during stack unwinding My. Class mc 6("mc 6"); if (which. To. Fail == "main") throw std: : exception(); f(); My. Class mc 7("mc 7"); } catch (. . . ) { My. Class mc 8("mc 8"); } // resume here after handling the exception My. Class mc 9("mc 9"); } Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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 -2019

COMP 345 - Advanced Program Design with C++ 16 Exception handling: exception specification •

COMP 345 - Advanced Program Design with C++ 16 Exception handling: exception specification • Exception specifications: throw clause double divide(double d. Numerator, double d. Denominator) throw (Divide. By. Zero. Exception); • Funtion divide can only throw exceptions of Divide. By. Zero. Exception. void safe. Function(int i. Foo) throw(); • Function safe. Function cannot throw any type of exception. void free. For. All(int i. Bar); • Function free. For. All can throw any type of exception. • Seems a great idea, but this is extremely restrictive and leads to very tedious programming, as thrown exceptions tend to propagate. • Problem: Any function that calls a function that may throw either needs to make the call in a try block and catch the exception, or itself have a throw clause that specifies that it may throw. • This is referred to in Java as the “catch or declare rule”. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 17 Exception handling: exception specification •

COMP 345 - Advanced Program Design with C++ 17 Exception handling: exception specification • In C++, exception specification clauses do not mean that the code executed by the function is guaranteed to throw only exception listed in its throw list. • Rather, it means that the exception handling mechanism will make the program call unexpected() if a function throws an exception type that in not listed in its throw clause. • The default behavior of unexpected() is to call terminate(), which abruptly stops the program’s execution. • This verification is only used at runtime. The compiler will not verify that all exceptions potentially thrown by the code included in a function only throw exceptions listed in its throw list. • Exception specification has been eliminated in C++11. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 18 Exception handling: standard exceptions Parent

COMP 345 - Advanced Program Design with C++ 18 Exception handling: standard exceptions Parent class of all the standard C++ exceptions. Thrown by new if out of memory. std: : bad_alloc Thrown by dynamic_cast if target of cast std: : bad_cast outside of hierarchy of parameter. To handle unexpected exceptions. std: : bad_exception Thrown by typeid if parameter is NULL. std: : bad_typeid A logical error is detected, i. e. errors that std: : logic_error can be detected at compile time. A call is made with values outside of std: : domain_error acceptable range. std: : invalid_argument Invalid arguments used (when “range” is not applicable. The size limit of an object have been std: : length_error exceeded e. g. vector’s max_size An indexed container is used out of range of std: : out_of_range its valid index range, e. g. the at method of std: : vector A runtime error is detected, i. e. errors that std: : runtime_error can only be detected at runtime. Numeric type overflow was calculated. std: : overflow_error std: : exception std: : range_error std: : underflow_error Concordia University A value out of range was calculated Numeric type overflow was calculated. Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 19 Exception handling: example • An

COMP 345 - Advanced Program Design with C++ 19 Exception handling: example • An industrial boiler controlled by software. • It is connected to a pressure sensor and a pressure release valve. • It keeps the pressure within an acceptable range. • If the sensor is misbehaving, it shuts down the boiler by opening the valve. • If the valve is stuck, it calls an emergency. • It keeps a log of the pressure readings, as well as another log for operational events. • The hardware drivers can throw exceptions. • For security, the boiler controller should be shielded from those exceptions. • Thus, an exception handling layer is added. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 20 Exception handling: custom exception classes

COMP 345 - Advanced Program Design with C++ 20 Exception handling: custom exception classes • Any class can be thrown as an • • exception. All that is really needed to be used as an exception is to be a type. Custom exception classes can be derived from the standard exception class. The only particularity of this class is that it offers a members function what() to return a string that allows the programmer to store a descriptive message on the nature of the circumstances that led to the error. Generally, this string is passed to the constructor upon creation of the exception. Concordia University class Hardware. Exception : public exception { public: Hardware. Exception(); char * exc_time; const char * what() const; }; class Actuator. Exception : public Hardware. Exception { friend ostream& operator<<(ostream &output, const Actuator. Exception &e); public: Actuator. Exception(Hardware. State s); Hardware. State hw_State; }; class Sensor. Exception : public Hardware. Exception { friend ostream& operator<<(ostream &output, const Sensor. Exception &e); public: Sensor. Exception(int v); int value. Read; }; class Overload. Pressure. Exception : public Sensor. Exception { public: Overload. Pressure. Exception(int v); }; class Stuck. Valve. Exception : public Actuator. Exception { public: Stuck. Valve. Exception(Hardware. State s); }; Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 21 Exception handling: exception classes hierarchy

COMP 345 - Advanced Program Design with C++ 21 Exception handling: exception classes hierarchy Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 22 Exception handling: custom exception classes

COMP 345 - Advanced Program Design with C++ 22 Exception handling: custom exception classes implementation • An exception class can be made to store any other useful information, e. g. the time where the exception was thrown. • The what() function can also be overridden to provide information otherwise than assuming the programmer to provide a string. • As for any other class, one can also overload operators to manipulate user-defined exceptions, e. g. stream input/output operators. Concordia University Hardware. Exception: : Hardware. Exception() { time_t now = time(0); exc_time = ctime(&now); } const char * Hardware. Exception: : what() const { return typeid(*this). name(); } Actuator. Exception: : Actuator. Exception(Hardware. State s) : hw_State(s){ cout << "in Actuator. Exception constructor" << endl; }; ostream& operator<<(ostream &output, const Actuator. Exception& e) { output << e. hw_State << " @ " << e. exc_time << " : " << e. what() << endl; return output; } Sensor. Exception: : Sensor. Exception(int v) : value. Read(v){}; ostream& operator<<(ostream &output, const Sensor. Exception& e) { output << e. value. Read << " @ " << e. exc_time << " : " << e. what() << endl; return output; } Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 23 Exception handling: example Boiler: :

COMP 345 - Advanced Program Design with C++ 23 Exception handling: example Boiler: : Boiler(){ cout << "in Boiler constructor" << endl; emergency. File. open("Emergency. File. txt"); emergency. File << "STARTING BOILER CONTROLLER" << endl; pressure. Report. File. open("pressure. Report. File. txt"); pressure. Report. File << "STARTING BOILER CONTROLLER" << endl; ps = new Pressure. Sensor. Connector(new Pressure. Sensor(), this); prv = new Pressure. Release. Valve. Connector(new Pressure. Release. Valve(stuck), this); boiler. State = safe; srand(time(0)); } void Boiler: : shutdown(){ cout << "in Boiler: : shutdown" << endl; emergency. File << "Engaging shutdown procedure. " << endl; prv->open(); emergency. File << "BOILER CONTROLLER WAS SHUT DOWN" << endl; pressure. Report. File << "BOILER CONTROLLER WAS SHUT DOWN" << endl; } void Boiler: : start(){ cout << "in Boiler: : start()" << endl; int i; while (boiler. State == safe){ Sleep(1000); i = ps->get. Pressure(); } class Boiler { } public: Boiler(); Boiler: : ~Boiler(){ ~Boiler(); emergency. File. close(); void shutdown(); pressure. Report. File. close(); void start(); } Pressure. Sensor. Connector* ps; Pressure. Release. Valve. Connector* ofstream emergency. File; ofstream pressure. Report. File; Boiler. State boiler. State; }; Concordia University • Boiler: connected to a temperature sensor and pressure release valve. • Reports pressure in pressure. Report. File. • Reports errors in Emergency. File. • Repeatedly reads the pressure. • No exception handling here. enum Actuator. State { opened, closed }; enum Boiler. State { safe, unsafe, critical }; enum Hardware. State { operational, stuck }; prv; int main() { Boiler b; b. start(); } Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 24 Exception handling: example int Pressure.

COMP 345 - Advanced Program Design with C++ 24 Exception handling: example int Pressure. Sensor: : get. Pressure(){ cout << "in Pressure. Sensor: : get. Pressure()" << endl; \ simulate a pressure reading int pressure = rand() % 105 - 1; if (pressure < 0) { cout << "about to throw Negative. Pressure. Exception" << endl; throw new Negative. Pressure. Exception (pressure); } if (pressure > 100) { cout << "about to throw Overload. Pressure. Exception" << endl; throw new Overload. Pressure. Exception (pressure); } return pressure; } • Pressure. Sensor: Pressure. Sensor. Connector : : Pressure. Sensor. Connector( Pressure. Sensor *ps, Boiler *b) : ps(ps), b(b) { cout << "in Pressure. Sensor. Connector constructor" << endl; }; int Pressure. Sensor. Connector : : get. Pressure(){ cout << "in Pressure. Sensor. Connector: : get. Pressure()" << endl; int pressure = 999; try{ pressure = ps->get. Pressure(); time_t now = time(0); char *read_time = ctime(&now); b->pressure. Report. File << pressure << " @ " << read_time << endl; } catch (Sensor. Exception* e){ cout << "catching Sensor. Exception in Pressure. Sensor. Connector: : get. Pressure()" << endl; b->emergency. File << *e; b->boiler. State = unsafe; b->shutdown(); } return pressure; } Concordia University hardware component that reports pressure reading. If out of range, throw exception. • Connected to the boiler using a connector that reports pressure readings and catches the exceptions thrown by the sensor and reports them. class Pressure. Sensor { public: int get. Pressure(); }; class Pressure. Sensor. Connector { private: Pressure. Sensor* ps; Boiler* b; public: Pressure. Sensor. Connector(Pressure. Sensor *ps, Boiler *b); int get. Pressure(); }; Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 25 Exception handling: example // stuck

COMP 345 - Advanced Program Design with C++ 25 Exception handling: example // stuck valve can be simulated by passing “stuck” to the constructor Pressure. Release. Valve : : Pressure. Release. Valve( Hardware. State s = operational) : hw_state(s), act_state(closed){}; • Pressure. Release. Val ve: hardware component that opens/closes the boiler’s container. If the valve is stuck throw an exception. If the valve is stuck closed, put the boiler in critical state. void Pressure. Release. Valve : : close(){ if (hw_state == stuck && act_state == opened) { throw new Stuck. Valve. Exception (hw_state); } else { act_state = closed; } } void Pressure. Release. Valve : : open(){ if (hw_state == stuck && act_state == closed) { throw new Stuck. Valve. Exception (hw_state); } else { act_state = opened; } } Pressure. Release. Valve. Connector : : Pressure. Release. Valve. Connector (Pressure. Release. Valve *prv, Boiler *b) : prv(prv), b(b){}; void Pressure. Release. Valve. Connector : : close(){ try{ prv->close(); } catch (Stuck. Valve. Exception e) { b->emergency. File << e; } } void Pressure. Release. Valve. Connector : : open(){ try{ prv->open(); } catch (Stuck. Valve. Exception * e) { b->boiler. State = critical; b->emergency. File << *e; } } Concordia University class Pressure. Release. Valve { public: Pressure. Release. Valve(Hardware. State s); void close(); void open(); private: Actuator. State act_state; Hardware. State hw_state; }; class Pressure. Release. Valve. Connector { private: Pressure. Release. Valve* prv; Boiler* b; public: Pressure. Release. Valve. Connector( Pressure. Release. Valve *prv, Boiler *b); void close(); void open(); }; Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 26 Exception handling: significance • Does

COMP 345 - Advanced Program Design with C++ 26 Exception handling: significance • Does the exception handling mechanism solve our error handling problems? • No, it is only a mechanism. • Does the exception handling mechanism provide a radically new way of dealing with errors? • No, it simply provides a formal and explicit way of applying the standard techniques. • The exception handling mechanism 1. Makes it easier to adhere to good programming practices. 2. Gives error handling a more regular style. 3. Makes error handling code more readable. 4. Makes error handling code more amenable to tools. [Bjarne Stroustrup] Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 27 Exceptions: overhead • The exception

COMP 345 - Advanced Program Design with C++ 27 Exceptions: overhead • The exception handling mechanism has a very minimal performance cost if no • • • exception is thrown. If an exception is thrown, the cost of the stack unwinding is roughly comparable to the cost of the normal function call/resolution mechanism. The cost of searching for the appropriate catch is what is the most costly when an exception is thrown. Additional data structures are required to track the call stack after a try block is entered, and additional instructions are required to unwind the stack if an exception is thrown. In most scenarios, the cost in performance and memory footprint is not significant. The adverse effect of exceptions on performance is likely to be significant only on very memory-constrained systems, or in performance-critical loops where an exception is likely to be thrown regularly and the code to handle it is tightly coupled to the code that throws it. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

COMP 345 - Advanced Program Design with C++ 28 Exceptions: overhead • The real

COMP 345 - Advanced Program Design with C++ 28 Exceptions: overhead • The real cost of exception handling is in the difficulty of designing exception-safe code. • Constructors that throw exceptions are problematic: if a constructor fails, the object is not created, which makes it hard to recover from. This is even more problematic with class hierarchies, which require a sequence of constructors to succeed in order for an object to be fully constructed. In C++, an object is either successfully constructed or it does not exist. • Even more problematic is that if an object is not fully created, its destructor is never called, leading to partially-created objects that create resource leaks. • Destructors should never be allowed to throw an exception if their code throws an exception, it should keep it contained and be resolved locally. • Dynamic memory allocation makes things more difficult, as stack unwinding does not take into consideration dynamically allocated local variables. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019

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

COMP 345 - Advanced Program Design with C++ 29 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. Bjarne Stroustrup. The C++ Programming Language. Chapter 13: Exception Handling. Addison-Wesley. Fourth Edition, 2014. A Coder’s Journey. Top 15 C++ Exception Handling Mistakes and How to Avoid Them. Concordia University Department of Computer Science and Software Engineering Joey Paquet, 2007 -2019