Code Complete Ch.8 Defensive Programming

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 .
This entry was posted in Unknown and tagged . Bookmark the permalink.

Leave a comment