Defensive programming is assuming a hostile environment for code and handling contingencies that may arise. Defensive programming is important because nonsensical execution can cause arbitrary damage to any module. Defensive programming contains the error to the module that first detected the error. It may then forward the error to a caller. The goal is to place the code in a straight-jacket that prevents deviate behavior.
Defensive programming is particularly important in user interfaces. Users tend to respond to errors and uncertainty with action. They defer error correction if possible. Dialogs can tolerate spelling errors, alternative formats, and missing data. All actions should be safe and reversible. Edits can be saved continually. Inconsistent data can be marked for checking later.
Data structures should be self-checking and self-correcting. For example, disk blocks can contain sufficient data to restore directory information. File systems should contain enough redundant data to limit the damage of lost blocks.
Data structures can be designed to survive memory errors. Most programs may detect such errors but few attempt to correct them. If memory errors are likely, error detection codes may be used to automatically correct the errors.
Defensive programming should report detected errors. If so, some other error that caused the failure will go undetected. Defensive programming should not attempt to be perfect. It should catch errors fairly soon after they occur. But defensive programming is important even in fully typed checked programs. There are too many possible sources of error to justify pretending that errors can not occur. (cbb 4/98)