Motivation for C Exceptions Void Number operator const

Motivation for C++ Exceptions Void Number: : operator/= • (const double denom) { if (denom == 0. 0) { // what to do here? } • m_value /= denom; } Need to handle cases where program cannot behave normally – E. g. , zero denominator for division Otherwise bad things happen – Program crashes – Wrong results • Could set value to Number: : Na. N – – I. e. , a special “not-a-number” value Must avoid using a valid return value… … which can be difficult (e. g. , for int) Anyway, caller might fail to check for it • Exceptions offer a better alternative CSE 332: C++ Exceptions

C++ Exception Syntax void foo() throw 2; } throw (int) { • Can throw any type • A function’s declaration can list types it can throw – Otherwise the function may try { throw any defined type foo(); • Can catch and inspect or } catch (int &i) { use exceptions cout << “caught ” • “Default” catch block is << i << endl; indicated by three dots } – Catches every type catch (. . . ) { cout << “another exception” << endl; } CSE 332: C++ Exceptions

C++11 Exceptions • C++11 standardizes a hierarchy of exception classes – To access these classes #include <stdexcept> • Two main kinds (subclasses) of exception – Run time errors (overflow errors and underflow errors) – Logic errors (invalid arguments, length error, out of range) • Several other subclasses of exception – – Bad memory allocation Bad cast Bad type id Bad exception • You can also declare other subclasses of these – Using the class and inheritance material in later lectures CSE 332: C++ Exceptions

Overview of C++ Exceptions • Normal program control flow is halted – At the point where an exception is thrown • The program call stack “unwinds” – Stack frame of each function in call chain “pops” – Variables in each popped frame are destroyed – This goes on until an enclosing try/catch scope is reached • Control passes to first matching catch block – Can handle the exception and continue from there – Can free some resources and re-throw exception • Let’s look at the call stack and how it behaves – Good way to explain how exceptions work (in some detail) – Also a good way to understand normal function behavior CSE 332: C++ Exceptions

A More Detailed Look at Stack Frames • In general, the structure is common – A chunk of memory representing the state of an active function call – Pushed on program call stack at run-time • g++ -s generated machine code (in assembly language) – can be used to deduce exact structure for a given platform • Each stack frame contains: – – A pointer to the previous stack frame The return address (i. e. , just after point from which function was called) The parameters passed to the function (if any) Automatic (local) variables for the function • Sometimes called “stack variables” automatic variables parameters previous frame pointer return address CSE 332: C++ Exceptions
![Illustrating the Call Stack (1/8) int main (int argc, const char *argv[]) { Number Illustrating the Call Stack (1/8) int main (int argc, const char *argv[]) { Number](http://slidetodoc.com/presentation_image_h2/96c87dd17e337187e8b470309a6867b2/image-6.jpg)
Illustrating the Call Stack (1/8) int main (int argc, const char *argv[]) { Number n(8. 1); • Stack frame for function main – Pushed on program call stack try { – With stack variable n – With parameters argc and argv n /= 0. 0; cout << n << endl; } catch (int) { return 1; } • Note that parameters are initialized at frame creation • Variables are not necessarily initialized at frame creation – May occur later in called function return 0; n m_value } main argc CSE 332: C++ Exceptions argv
![Illustrating the Call Stack (2/8) int main (int argc, const char *argv[]) { Number Illustrating the Call Stack (2/8) int main (int argc, const char *argv[]) { Number](http://slidetodoc.com/presentation_image_h2/96c87dd17e337187e8b470309a6867b2/image-7.jpg)
Illustrating the Call Stack (2/8) int main (int argc, const char *argv[]) { Number n(8. 1); • Number constructor called try { – Stack frame created n /= 0. 0; cout << n << endl; } catch (int) { return 1; } n Number: : Number(const double n) this return 0; n m_value } main argc CSE 332: C++ Exceptions argv

Illustrating the Call Stack (3/8) Number: : Number(const double n) : m_value(n) { } • Enter Number constructor – m_value is set in object • How do we know which m_value to set? – Implicit this pointer Number: : Number(const double n) n this n m_value main argc CSE 332: C++ Exceptions argv

Illustrating the Call Stack (4/8) Number: : Number(const double n) : m_value(n) { } • Return from constructor – Its stack frame is popped – Returns to main n m_value main argc CSE 332: C++ Exceptions argv

Illustrating the Call Stack (5/8) int main (int argc, char **argv) { Number n(8. 1); • Call try { n /= 0. 0; cout << n << endl; } catch (int) { return 1; } operator/= on n – New stack frame created – Copy 0. 0 into n – Set this Number: : operator/=(const double denom) return 0; denom this n m_value } main argc CSE 332: C++ Exceptions argv

Illustrating the Call Stack (6/8) void Number: : operator/=(const double denom) { if (denom == 0. 0) { throw 0; } • Test denom against 0. 0 – Test succeeds – throw integer 0 m_value /= denom; } Number: : operator/=(const double denom) denom this n m_value main argc CSE 332: C++ Exceptions argv

Illustrating the Call Stack (7/8) void Number: : operator/=(const double denom) { if (denom == 0. 0) { throw 0; } • throw unwinds stack • Skips over rest of function • Returns to caller value_ /= denom; } n m_value main argc CSE 332: C++ Exceptions argv

Illustrating the Call Stack (8/8) int main (int argc, char **argv) { Number n(8. 1); • We’ve try { n /= 0. 0; cout << n << endl; } catch (int) { return 1; } reached an enclosing try/catch scope – So stack unwinding stops • Control jumps to first matching catch block – Skips over intervening cout statement (no output!) return 0; n m_value } main argc CSE 332: C++ Exceptions argv

Catching Exceptions in C++ try { // can throw exceptions } catch (Derived &d) { // Do something } catch (Base &d) { // Do something else } catch (. . . ) { // Catch everything else } CSE 332: C++ Exceptions • Control jumps to first matching catch block • Order matters if multiple possible matches – Especially with inheritance-related exception classes – Put more specific catch blocks before more general ones – Put catch blocks for more derived exception classes before catch blocks for their respective base classes

More About Catching Exceptions in C++ try { // can throw exceptions } catch (Derived &d) { // Do something } catch (Base &d) { // Do something else } catch (. . . ) { // Catch everything else } CSE 332: C++ Exceptions • catch(. . . ) – Catches any type • throw; – Throws nothing (cannot catch) – Often preferable to exit(1) – But usually it’s better to throw something • E. g. , a special type • E. g. , at least an int

Exception Specifications (do not use them) // can throw anything void Foo: : baz(); // promises not to throw void Foo: : baz() throw(); // promises to only throw int void Foo: : baz() throw(int); • Added in C++98, deprecated in C++11 • Make promises to the calling function – Empty throw clause promises no exceptions – Can list multiple types (comma separated) • By default, a function can throw whatever it wants // only char or int void Foo: : baz() throw(char, int); CSE 332: C++ Exceptions – Throw clause in function signature limits what that function body can throw – But can call code that leaves off throw clause

Rules of Thumb for Using C++ Exceptions • Use exceptions to handle any cases where the program cannot behave normally – Do not use exceptions as a way to control program execution under normal operating conditions • Don't let a thrown exception propagate out of the main function uncaught – Instead, always catch any exceptions that propagate up – Then return a non-zero value to indicate program failure • Don’t use or rely on exception specifications – A false promise if you declare them, unless you have fully checked all the code used to implement that interface – No guarantees that they will work for templates, because a template parameter could leave them off and then throw CSE 332: C++ Exceptions
- Slides: 17