130 likes | 156 Views
Talk. Speaker: Howard Heck, Intel Corporation Title: "7 Habits of Highly Effective Engineers" Abstract: What makes a great engineer great? Analytical and mathematical skills are a big part of it, but it may not surprise you to learn that there is much more
E N D
Talk Speaker: Howard Heck, Intel Corporation Title: "7 Habits of Highly Effective Engineers" Abstract: What makes a great engineer great? Analytical and mathematical skills are a big part of it, but it may not surprise you to learn that there is much more to it than that. In this talk, I will provide some ideas and opinions as to just what the other characteristics of highly successful engineers might be. Date: Tuesday 11/28 Time: 4:00 pm Location: Tech L324
Basics of exception handling • The problem: • How to handle runtime errors. • Class example: • Consider the implementation of a stack. We'd like to handle errors such as trying to pop an empty stack, push into a full stack, etc. • We will base our stack implementation on a vector. class intstack { private: int itop; // index of top element vector<int> istack; ... };
Basics of exception handling • Traditional solutions (C, old C++) • When an error occurs, execution terminates: int intstack::top( ) { if (empty()) { cerr << "Error: Attempt to pop empty stack." << endl; exit(POPEMPTY); } return istack[itop]; };
Basics of exception handling • Traditional solutions (C, old C++) • Every method returns an indication of whether its operation succeeded: int main () { ... intstack S; int val; if (!S.top(val)) { do_something(); // val does not contain valid data! } else { ... } ... } bool intstack::top(int &val ) { if (!empty()) { val = istack[itop]; return true; } return false; };
Basics of exception handling • Traditional solutions (C, old C++) • Set the value of a global error variable • The value will be checked after an operation has been completed: int main () { ... intstack S; errorcode = GOOD; int val; S.top(val); if (errorcode == POPEMPTY) take_some_action() ... return 0; } extern int errocode; ... void intstack::top(int &val ) { if (empty()) errorcode = POPEMPTY; else val=istack[itop]; };
Basics of exception handling • Traditional solutions (C, old C++) • Set the value of a global error variable • For errors caused by system calls, we can use the global variable errno which is defined in <errno.h> and is automatically assigned an error code. • An associated string message can be retrieved by using strerror(errno). This is defined in <cstring> • An error message is typically printed using perror(message)
Basics of exception handling • Traditional solutions (C, old C++) • errno examples #include <stdio.h> int main () { FILE * inFile; inFile = fopen ("nonexistent.txt","r"); if (inFile == NULL) perror ("Error:"); else fclose (inFile); return 0; } Output: Error: No such file or directory
Basics of exception handling • Traditional solutions (C, old C++) • errno examples #include <stdio.h> #include<errno.h> #include<string.h> int main () { FILE * inFile; inFile = fopen ("nonexistent.txt","r"); if (inFile == NULL) printf ("Error: %s\n", strerror(errno)); else fclose (inFile); return 0; } Output: Error: No such file or directory
Basics of exception handling • Modern C++ solution • C++ provides a mechanism for exception handling. • When an error occurs we say that an exception is raised or thrown. • A separate piece of code (handler) is then used to handle the exception. • General syntax: try { // try some code that may raise an exception // if an error occurs throw Exception(); // throw an Exception object } catch (Exception e) { // handle the exception } // there may be additional catch sections if the try code // can generate more than one type of exception.
Basics of exception handling void intstack::top(int &val ) { if (empty()) throw topEmpty(); else val=istack[itop]; }; int main () { intstack S; int val; try { S.top(val); } catch (topEmpty) { cerr << "Attempt to access empty stack"; return 1; } return 0; }
Basics of exception handling int main () { intstack S; int val; try { S.top(val); } catch (topEmpty) { cerr << "Attempt to access empty stack"; return 1; } return 0; } void intstack::top(int &val ) { if (empty()) throw topEmpty(); else val=istack[itop]; }; This automatically creates a (nameless) topEmpty object. So let's create the topEmpty class: class topEmpty { public: topEmpty() { } };
Basics of exception handling • What if we'd like additional information? • For example, if there an exception is raised when trying to push a value (e.g. because the stack overflows), we'd like the exception handler to print the value whose insertion caused the exception. • Easy! Just save it in the exception object (as member data).
Basics of exception handling class pushFull { private: int _value; public: pushFull() { } pushFull(int v) :_value(v) {} int value() {return _value;} }; void intstack::push(int val ) { if (full()) throw pushFull(val); else istack[++itop] = val; }; int main () { intstack S; int val=5; try { S.push(val); } catch (pushFull exc) { cerr << "Could not push " << exc.value(); } return 0; }