e.g. European Space Agency (ESA) Arianne 5 Crash
In Eiffel, The Precondition of a routine is the assertion designated by 'require'
The postcondition is designated by 'ensure'
Example:
Square_root(x:REAL):REAL is
require: x >= 0
<function body>
ensure: Result*Result = x
The class invariant is an assertion 'global' to all routines in the class.
By giving a precise precondition and postcondition of a routine we are in effect specifying what the routine is supposed to do.
From B. Meyer
quote:
To improve software reliability, the first and perhaps most difficult problem is to define as precisely as possible, for each software element, what it is supposed to do. The immediate objection is that specifying a module's purpose will not ensure that it will achieve that specification; this is obviously true, but:
... the presence of a specification, even if it does not fully guarantee the module's correctness, is a good basis for systematic testing and debugging.
end quote
Writing a program is a like a contract between the supplier and the client.
The supplier routine will deliver the result specified by the postcondition, as long as the client (calling) routine fulfills the requirements of the precondition.
See page 342 OOSC 2nd Ed
Example:
A client routine of the square_root program must supply an value >= 0, otherwise the supplier routine will not provide the proper result.
In the case of the square_root program, defensive programming could use instead of a precondition, a defensive 'if -then' e.g.
Square_root(x:REAL):REAL is
if x < 0 then
<output error message>
else
<function body>
end
Problems with Defensive Programming:
see pg 11-12 Invitation to Eiffel (.pdf version)