DOC PREVIEW
Stanford CS 106A - Error Handling

This preview shows page 1-2-3-4-5 out of 15 pages.

Save
View full document
View full document
Premium Document
Do you want full access? Go Premium and unlock all 15 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 15 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 15 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 15 pages.
Access to all documents
Download any document
Ad free experience
View full document
Premium Document
Do you want full access? Go Premium and unlock all 15 pages.
Access to all documents
Download any document
Ad free experience
Premium Document
Do you want full access? Go Premium and unlock all 15 pages.
Access to all documents
Download any document
Ad free experience

Unformatted text preview:

Chapter 12: Error HandlingChapter 12: Error Handling_________________________________________________________________________________________________________Forty years ago, goto-laden code was considered perfectly good practice. Now we strive to write structured control flows. Twenty years ago, globally accessible data was considered perfectly good practice. Now we strive to encapsulate data. Ten years ago, writing functions without thinking about the impact of exceptions was considered good practice. Now we strive to write ex-ception-safe code.Time goes on. We live. We learn.– Scott Meyers, author of Effective C++ and one of the leading experts on C++. [Mey05]In an ideal world, network connections would never fail, files would always exist and be properly format-ted, users would never type in malformed input, and computers would never run out of memory. Realist-ically, though, all of the above can and will occur and your programs will have to be able to respond to them gracefully. In these scenarios, the normal function-call-and-return mechanism is not robust enough to signal and report errors and you will have to rely on exception handling, a C++ language feature that re-directs program control in case of emergencies.Exception handling is a complex topic and will have far-reaching effects on your C++ code. This chapter introduces the motivation underlying exception handling, basic exception-handling syntax, and some ad-vanced techniques that can keep your code operating smoothly in an exception-filled environment.A Simple ProblemUp to this point, all of the programs you've written have proceeded linearly – they begin inside a special function called main, then proceed through a chain of function calls and returns until (hopefully) hitting the end of main. While this is perfectly acceptable, it rests on the fact that each function, given its para-meters, can perform a meaningful task and return a meaningful value. However, in some cases this simply isn't possible.Suppose, for example, that we'd like to write our own version of the CS106B/X StringToInteger func-tion, which converts a string representation of an number into an int equivalent. One possible (partial) implementation of StringToInteger might look like this:* int StringToInteger(const string &input) { stringstream converter(input); int result; // Try reading an int, fail if we're unable to do so. converter >> result; if (converter.fail()) // What should we do here? char leftover; // See if anything's left over. If so, fail. converter >> leftover; if (!converter.fail()) return result; else // What should we do here? }* This is based off of the GetInteger function we covered in the chapter on streams. Instead of looping and re-prompting the user for input at each step, however, it simply reports errors on failure.- 364 - Chapter 12: Error HandlingIf the parameter input is a string with a valid integer representation, then this function simply needs to perform the conversion. But what should our function do if the parameter doesn't represent an integer? One possible option, and the one used by the CS106B/X implementation of StringToInteger, is to call a function like Error that prints an error and terminates the program. This response seems a bit drastic and is a decidedly suboptimal solution for several reasons. First, calling Error doesn't give the program a chance to recover from the problem. StringToInteger is a simple utility function, not a critical infra-structure component, and if it fails chances are that there's an elegant way to deal with the problem. For example, if we're using StringToInteger to convert user input in a text box into an integer for further processing, it makes far more sense to reprompt the user than to terminate the program. Second, in a very large or complicated software system, it seems silly to terminate the program over a simple string error. For example, if this StringToInteger function were used in an email client to convert a string represent-ation of a time to an integer format (parsing the hours and minutes separately), it would be disastrous if the program crashed whenever receiving malformed emails. In essence, while using a function like Error will prevent the program from continuing with garbage values, it is simply too drastic a move to use in ser-ious code.This approach suggests a second option, one common in pure C – sentinel values. The idea is to have func-tions return special values meaning “this value indicates that the function failed to execute correctly.” In our case, we might want to have StringToInteger return -1 to indicate an error, for example. Compared with the “drop everything” approach of Error this may seem like a good option – it reports the error and gives the calling function a chance to respond. However, there are several major problems with this meth-od. First, in many cases it is not possible to set aside a value to indicate failure. For example, suppose that we choose to reserve -1 as an error code for StringToInteger. In this case, we'd make all of our calls to StringToInteger as if (StringToInteger(myParam) == -1) { /* ... handle error ... */ }But what happens if the input to StringToInteger is the string "-1"? In this case, whether or not the StringToInteger function completes successfully, it will still return -1 and our code might confuse it with an error case.Another serious problem with this approach is that if each function that might possibly return an error has to reserve sentinel values for errors, we might accidentally check the return value of one function against the error code of another function. Imagine if there were several constants floating around named ERROR, STATUS_ERROR, INVALID_RESULT, etc., and whenever you called a function you needed to check the return value against the correct one of these choices. If you chose incorrectly, even with the best of in -tentions your error-checking would be invalid.Yet another shortcoming of this approach is that in some cases it will be impossible to reserve a value for use as a sentinel. For example, suppose that a function returns a vector<double>. What special vec-tor<double> should we choose to use as a sentinel?However, the most serious problem with the above approach is that you as a programmer can ignore the return value


View Full Document

Stanford CS 106A - Error Handling

Download Error Handling
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Error Handling and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Error Handling 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?