I'm having trouble differentiating the two. If they do not usually overlap, how are they different? What is an example of something that would be a precondition but not an invariant?
-
What definitions are you using for "precondition" and "invariant"? – Greg Hewgill Dec 11 '12 at 19:16
-
By precondition, I mean that when methods are called, they are under the assumption that certain things are true about the environment of the container. By invariants, I mean the the state of the container being unchanged during and after the invoking of any method. – dtgee Dec 11 '12 at 19:24
-
What is "the container"? Your question doesn't mention containers. – Greg Hewgill Dec 11 '12 at 19:28
-
Well, actually I don't really mean containers, I mean inside any class in general where invariants/preconditions are considered. – dtgee Dec 11 '12 at 19:32
4 Answers
Some other answers attempt to define the terms “precondition” and “invariant”. I think e.g. Wikipedia does a much better job of that, so instead I have just linked to Wikipedia for definitions. Anyway, if the question was solely about definitions, then it would have been an RTFM question and I would have voted to close it, instead of answering.
“If [preconditions and invariants] do not usually overlap, how are they different?”
A method's preconditions can always be regarded as a single precondition formed from the conjunction of individual sub-conditions, and so we often speak of and reason about “the” precondition.
For a public method one of the sub-preconditions is always the class invariant, so yes, there is often an overlap.
Things get more tricky when considering internal (private
and protected
) methods. Often a public method works by temporarily breaking the class invariant and then restoring it. During the period of invalid class invariant it might call some internal helper methods, and those internal helper methods can't very well have the class invariant included in their preconditions.
Things get even more tricky when one attempts to clearly differentiate between public interface and implementation detail, and the previous attempt to introduce Eiffel-like Design By Contract (DBC) assertions into C++ stranded on this.
The in practice is easy enough, though, because for the in-practice one can just avoid the very tricky cases, design around it, so to speak.
“What is an example of something that would be a precondition but not an invariant?”
For example,
class Foo
{
public:
void add( Bar* p )
{
assert( p != 0 ); // Precondition unrelated to the class invariant
// ... whatever
}
};

- 142,714
- 15
- 209
- 331
A precondition is simply something that must be true before but not necessarily during or after. An invariant, as the name suggests will not change at any point in time. For example, let us say that I want to normalize a vector. A precondition could be that it's current norm must not be 0 (because I that would incur a division by zero). The operation of normalization would change the norm of the vector which means it would be a precondition yet not an invariant.

- 15,826
- 5
- 46
- 62
An invariant is typically some property of your state. For example you might assert that 1 <= x <= 100
always.
A pre-condition applies to a method call. For example if the class containing x
above has a method Foo(int y, int z)
the precondition might be y < x
and z > 10000
for the function call to be valid.

- 95,107
- 10
- 109
- 188
The short answer is yes. Preconditions, postconditions and invariants are essentially different facets of the same thing.
A precondition is an "instantaneous" check before completing an operation. A postcondition is an "instantaneous" check after completing an operation. An invariant is a check that persists for some time.
For example, if you have a square root function that requires its argument to be >= 0, that's a precondition as it's a check conducted prior to an operation.
On the other hand if you have a class with members x & y, such that x > y at all times, that's an invariant as the condition persists for some time (during the life of your object). Likewise, if you have a loop and some condition must hold through every iteration of the loop, that too is an invariant, as the check persists for some time. Generally, the terms class invariant and loop invariant will be used to specify the type of invariant.

- 3,822
- 1
- 16
- 23