8.1 Protecting Your Program from Invalid Inputs.
“Garbage in, Garbage out” not allowed in modern programming.
- Check the values of all data from external sources.
- Check the values of all routine input parameters
- Decide how to handle bad inputs
8.2 Assertions
Use assertions to check :
- that an input parameter’s value falls into expected range.
- that a file or stream is open(or closed)
- that a file or stream is open for read-only, write-only or both read and write.
- that the value of an input-only variable is not changed by a routine.
- that a point is non-null.
- that an array or other containers passed in has at least X number of elements.
- that a table has been initialized to contain real values.
- that a container is empty or (full)
- that the results from a highly optimized, complicated routine match the results from a slower but clearly written routine.
Guidelines for Using Assertions
- Use error- handling code for conditions you expect to occur; use assertions for conditions that should never occur.
- Avoid putting executable code into assertion.
- Use assertions to document and verify preconditions and postconditions.
preconditions: client codes' obligation to the code it calls.
postcondition: routines or classes' obligations to the code that uses it.
- For highly robust code, assert and then handle the error anyway.
8.3 Error-handling Techniques
- Return a neutral value
- Substitute the next piece of valid data.
- Return the same answer as the previous time.
- Substitute the closest legal value
- Log a warning message to file.
- Return an error code.
- Set the value to a status variable.
- Return status as the function’s return value
- Throw an exception by using language’s built-in exception mechanism.
- Call an error-handling routine/object. Adv. error-handling is centrilized, Disadv: this object is too tightly coupled with rest of the application and needs to be dragged if code ports to another place.
- Display an error message wherever the error is encountered. Adv. minimize error-handling overhead; Disadv, spread user interface messages through the entire application.
- Handle the error in whatever way works best locally.
- Shut down : fro safety-critical applications.
8.4 Exceptions
- Use exceptions t notify other parts of the program about errors that should not be ignored.
- Throw an exception only for conditions that are truly exceptional. : like assertion, exceptions are for events that should never occur.
- Don’t use exception to pass the buck. If you can handle the error locally, don’t pass it along, just handle it locally.
- Avoid throwing exceptions in constructors and destructors unless you catch them in the same place.
- Throw exceptions at the right level of abstraction.
- Include in the exception message all information the led to the exception
- Avoid empty catch blocks.
- Know the exception your library code throws.
- Consider building a centralized exception reporter.
- Standardize your project’s use of exceptions.
- In C++, standardize on what to throw, objects, data or pointers. Consider throwing only objects derived from the Exception class.
- Consider creating your own exception class which will serve as the base class for all exceptions thrown in your project.
- Define specific circumstances where code is allowed to use throw-catch syntax to perform error processing locally.
- Define specific circumstances where code is allowed to throw an exception that won’t be handled locally.
- Determine whether a centralized exception report will be used.
- Define whether exceptions are allowed in constructors and destructors.
- Consider alternative to exceptions : Don’t use exception just because your language provides exceptions. “Don’t program in a language, program into the language. ”
8.5 Barricade Your Program to Contain the Damaged Caused by Errors
Convert input data to proper type at input time.
8.6 Debugging Aids
- Don’t automatically apply production constraints to the development version. Be willing to trade speed and resource usage during development in exchange for built-in tools that can make development go more smoothly.
- Introduce debugging aids early.
- Use offensive programming
- Plan to remove debugging aids:
- Use version control tools and build tools like ant and make.
- Use a built-in preprocessor
- write your own preprocessor
- use debugging stubs.
8.7 Determine How Much Defensive Programming to Leave in Production Code
- Leave in the code that checks for important errors.
- Remove code that checks for trivial errors
- Remove code that results in hard crashes
- Leave in code that helps the program crash gracefully
- Log errors for your technical support personnel.
- Make sure the error message you leave in are friendly .