Chapter 5 - Chapter 5 Chapter Errors Bjarne Stroustrup

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 5 Chapter Errors Bjarne Stroustrup www.stroustrup.com/Programming Abstract Abstract When we program, we have to deal with When errors. Our most basic aim is correctness, but we must deal with incomplete problem specifications, incomplete programs, and our own errors. Here, we’ll concentrate on a key area: how to deal with unexpected function arguments. We’ll also discuss techniques for finding errors in programs: debugging and testing. testing. Stroustrup/Programming 2 Overview Overview Kinds of errors Argument checking Error reporting Error detection Exceptions Debugging Testing Stroustrup/Programming 3 Errors Errors “ … I realized that from now on a large part of my life would be spent finding and correcting my own mistakes.” spent Maurice Wilkes, 1949 When we write programs, errors are natural and unavoidable; When the question is, how do we deal with them? the Organize software to minimize errors. Eliminate most of the errors we made anyway. Debugging Testing Make sure the remaining errors are not serious. My guess is that avoiding, finding, and correcting errors is 95% My or more of the effort for serious software development. or You can do much better for small programs. You or worse, if you’re sloppy Stroustrup/Programming 4 Your Program Your 1. 2. 3. 4. 5. Should produce the desired results for all legal inputs Should give reasonable error messages for illegal inputs Need not worry about misbehaving hardware Need not worry about misbehaving system software Is allowed to terminate after finding an error 3, 4, and 5 are true for beginner’s code; often, we have to 3, worry about those in real software. worry Stroustrup/Programming 5 Sources of errors Sources Poor specification Incomplete programs “but sqrt() isn’t supposed to be called with -1 as its argument” but sqrt() -1 Unexpected input “but I’ll not get around to doing that until tomorrow” Unexpected arguments “What’s this supposed to do?” “but the user was supposed to input an integer” Code that simply doesn’t do what it was supposed to do “so fix it!” Stroustrup/Programming 6 Kinds of Errors Kinds Compile-time errors Link-time errors Run-time errors Syntax errors Type errors Detected by computer (crash) Detected by library (exceptions) Detected by user code Logic errors Detected by programmer (code runs, but produces Detected incorrect output) incorrect Stroustrup/Programming 7 Check your inputs Check Before trying to use an input value, check that Before it meets your expectations/requirements it Function arguments Data from input (istream) Stroustrup/Programming 8 Bad function arguments Bad The compiler helps: Number and types of arguments must match int area(int length, int width) { return length*width; } int x1 = area(7); int x2 = area("seven", 2); int x3 = area(7, 10); int x5 = area(7.5, 10); int x = area(10, -7); int // error: wrong number of arguments error: // error: 1st argument has a wrong type // error: // ok // ok // ok, but dangerous: 7.5 truncated to 7; // ok, // // most compilers will warn you most // this is a difficult case: this // the types are correct, the // but the values make no sense but Stroustrup/Programming 9 Bad Function Arguments Bad So, how about Alternatives Just don’t do that Hard to do systematically The function should check Rarely a satisfactory answer The caller should check int x = area(10, -7); Return an “error value” (not general, problematic) Set an error status indicator (not general, problematic – don’t do this) Throw an exception Note: sometimes we can’t change a function that Note: handles errors in a way we do not like handles Someone else wrote it and we can’t or don’t want to change Someone their code their Stroustrup/Programming 10 Stroustrup/Programming 10 Bad function arguments Bad Why worry? You want your programs to be correct Typically the writer of a function has no control over how Typically it is called it The beginning of a function is often a good place to check Writing “do it this way” in the manual (or in comments) is no Writing solution – many people don’t read manuals solution Before the computation gets complicated When to worry? If it doesn’t make sense to test every function, test some Stroustrup/Programming 11 Bad function arguments Bad Return an “error value” (not general, problematic) int area(int length, int width) // return a negative value for bad int input input { if(length <=0 || width <= 0) return -1; else return length*width; } So, “let the caller beware” int z = area(x,y); if (z<0) error("bad area computation"); // … // Problems What if I forget to check that return value? Stroustrup/Programming 12 Bad function arguments Bad Set an error status indicator (not general, problematic, don’t!) int errno = 0; // used to indicate errors // used int area(int length, int width) { if (length<=0 || width<=0) errno = 7; // || means or // means return length*width; } So, “let the caller check” int z = area(x,y); if (errno==7) error("bad area computation"); // … // Problems What if I forget to check errno? What errno How do I pick a value for errno that’s different from all others? How errno How do I deal with that error? Stroustrup/Programming 13 Bad function arguments Bad Report an error by throwing an exception class Bad_area { }; // a class is a user defined type class class // Bad_area is a type to be used as an exception is int area(int length, int width) { if (length<=0 || width<=0) throw Bad_area(); // note the () note return length*width; } Catch and deal with the error (e.g., in main()) Catch main() try { int z = area(x,y); // if area() doesn’t throw an exception // if doesn’t } // make the assignment and proceed make catch(Bad_area) { // if area() throws Bad_area(), respond // if throws cerr << "oops! Bad area calculation – fix program\n"; } Stroustrup/Programming 14 Exceptions Exceptions Exception handling is general You can’t forget about an exception: the program will You terminate if someone doesn’t handle it (using a try … catch) catch Just about every kind of error can be reported using Just exceptions exceptions You still have to figure out what to do about an You exception (every exception thrown in your program) exception Error handling is never really simple Error never Stroustrup/Programming 15 Out of range Out Try this vector<int> v(10); // a vector of 10 ints, // int // each initialized to the default value, 0, // // referred to as v[0] .. v[9] // v[0] v[9] for (int i = 0; i<v.size(); ++i) v[i] = i; // set values for set for (int i = 0; i<=10; ++i) // print 10 values (???) // print cout << "v[" << i << "] == " << v[i] << endl; vector’s operator[ ] (subscript operator) reports a bad vector’s operator[ index (its argument) by throwing a Range_error if you Range_error index use #include "std_lib_facilities.h" #include The default behavior can differ Stroustrup/Programming 16 Exceptions – for now Exceptions For now, just use exceptions to terminate For programs gracefully, like this programs int main() try { // … // } catch (out_of_range&) { // out_of_range exceptions // exceptions cerr << "oops – some vector index out of range\n"; } catch (…) { // all other exceptions // all cerr << "oops – some exception\n"; } Stroustrup/Programming 17 A function error() error() Here is a simple error() function as provided in std_lib_facilities.h error() std_lib_facilities.h Here This allows you to print an error message by calling error() This It works by disguising throws, like this: void error(string s) // one error string void one { throw runtime_error(s); } void error(string s1, string s2) // two error strings void two { error(s1 + s2); // concatenates error(s1 concatenates } Stroustrup/Programming 18 Using error( ) error( Example cout << "please enter integer in range [1..10]\n"; int x = -1; // initialize with unacceptable value (if possible) initialize cin >> x; if (!cin) // check that cin read an integer // check error("didn’t get a value"); error("didn’t if (x < 1 || 10 < x) // check if value is out of range check error("x is out of range"); error("x // if we get this far, we can use x with confidence Stroustrup/Programming 19 How to look for errors How When you have written (drafted?) a program, it’ll When have errors (commonly called “bugs”) have It’ll do something, but not what you expected How do you find out what it actually does? How do you correct it? This process is usually called “debugging” Stroustrup/Programming 20 Debugging Debugging How not to do it How not while (program doesn’t appear to work) { // pseudo code // pseudo Randomly look at the program for something that “looks odd” Change it to “look better” } Key question How would I know if the program actually worked correctly? Stroustrup/Programming 21 Program structure Program Make the program easy to read so that you have a Make chance of spotting the bugs chance Comment Use meaningful names Indent Try to avoid functions longer than a page Avoid complicated code sequences Use a consistent layout Your IDE tries to help (but it can’t do everything) You are the one responsible Break code into small functions Explain design ideas Try to avoid nested loops, nested if-statements, etc. (But, obviously, you sometimes need those) Use library facilities Stroustrup/Programming 22 First get the program to compile First Is every string literal terminated? cout << "Hello, << name << '\n'; // oops! oops! Is every character literal terminated? cout << "Hello, " << name << '\n; // oops! oops! Is every block terminated? if (a>0) { /* do something */ if do else { /* do something else */ } // oops! do oops! Is every set of parentheses matched? if (a x = f(y); f(y); // oops! // oops The compiler generally reports this kind of error “late” Stroustrup/Programming It doesn’t know you didn’t mean to close “it” later 23 First get the program to compile First Is every name declared? Did you include needed headers? (e.g., std_lib_facilities.h) std_lib_facilities.h Did Is every name declared before it’s used? Did you spell all names correctly? int count; char ch; /* … */ ++Count; /* … */ Cin>>c; // oops! // oops! // double oops! // double Did you terminate each expression statement with a Did semicolon? semicolon? x = sqrt(y)+2 z = x+3; // oops! // oops! Stroustrup/Programming 24 Debugging Debugging Carefully follow the program through the specified Carefully sequence of steps sequence Pretend you’re the computer executing the program Does the output match your expectations? If there isn’t enough output to help, add a few debug If output statements output cerr << "x == " << x << ", y == " << y << '\n'; Be very careful See what the program specifies, not what you think it See should say should That’s much harder to do than it sounds for (int i=0; 0<month.size(); ++i) { for( int i = 0; i<=max; ++j) { for( Stroustrup/Programming // oops! // oops! // oops! (twice) oops! 25 Debugging Debugging When you write the program, insert some checks When (“sanity checks”) that variables have “reasonable values” values” Function argument checks are prominent examples of this if (number_of_elements<0) error("impossible: negative number of elements"); if (largest_reasonable<number_of_elements) error("unexpectedly large number of elements"); if (x<y) error("impossible: x<y"); Design these checks so that some can be left in the Design program even after you believe it to be correct program It’s almost always better for a program to stop than to give It’s wrong results wrong Stroustrup/Programming 26 Debugging Debugging Pay special attention to “end cases” (beginnings and ends) (beginnings Pay Did you initialize every variable? Did the function get the right arguments? No elements No input Did you open your files correctly? The last element? Did you handle the empty case correctly? Did the function return the right value? Did you handle the first element correctly? To a reasonable value more on this in chapter 11 Did you actually read that input? Write that output? Stroustrup/Programming 27 Debugging Debugging “If you can’t see the bug, you’re looking in the If wrong place” wrong It’s easy to be convinced that you know what the problem It’s is and stubbornly keep looking in the wrong place is Don’t just guess, be guided by output Work forward through the code from a place you know is right Work backwards from some bad output how could that possibly happen? how Once you have found “the bug” carefully consider if Once fixing it solves the whole problem fixing so what happens next? Why? so It’s common to introduce new bugs with a “quick fix” “I found the last bug” is a programmer’s joke Stroustrup/Programming 28 Note Note Error handling is fundamentally more difficult and messy than Error “ordinary code” “ordinary There is basically just one way things can work right There are many ways that things can go wrong The more people use a program, the better the error handling The must be must If you break your own code, that’s your own problem And you’ll learn the hard way If your code is used by your friends, uncaught errors can cause you to If lose friends lose If your code is used by strangers, uncaught errors can cause serious grief And they may not have a way of recovering Stroustrup/Programming 29 Pre-conditions Pre-conditions What does a function require of its arguments? Such a requirement is called a pre-condition Sometimes, it’s a good idea to check it int area(int length, int width) // calculate area of a rectangle int calculate // length and width must be positive // length { if (length<=0 || width <=0) throw Bad_area(); return length*width; } Stroustrup/Programming 30 Post-conditions Post-conditions What must be true when a function returns? Such a requirement is called a post-condition int area(int length, int width) // calculate area of a rectangle int calculate // length and width must be positive // length { if (length<=0 || width <=0) throw Bad_area(); // the result must be a positive int that is the area // the // no variables had their values changed return length*width; } Stroustrup/Programming 31 Pre- and post-conditions Pre Always think about them If nothing else write them as comments Check them “where reasonable” Check a lot when you are looking for a bug This can be tricky How could the post-condition for area() fail after the precondition succeeded (held)? Stroustrup/Programming 32 Testing Testing How do we test a program? Be systematic Think of testing and correctness from the very start “pecking at the keyboard” is okay for very small programs and pecking for very initial tests, but is insufficient for real systems for When possible, test parts of a program in isolation E.g., when you write a complicated function write a little E.g., program that simply calls it with a lot of arguments to see how it behaves in isolation before putting it into the real program program We’ll return to this question in Chapter 26 Stroustrup/Programming 33 The next lecture The In the next two lectures, we’ll discuss the In design and implementation of a complete small program – a simple “desk calculator.” program Stroustrup/Programming 34 ...
View Full Document

This note was uploaded on 02/18/2012 for the course CSCE 121 taught by Professor Walter daugherity during the Fall '09 term at Texas A&M.

Ask a homework question - tutors are online