Every pre-, post-, and invariant condition violation represents a programming error, at an indeterminate point in the past, rendering the state of the computation unknown, and likely undefined, and definitely unrecoverable.
An exception, by definition, is to enable recovery from externally imposed events in a well-defined program state.
The only useful, meaningful response to discovering a contract violation is termination. Throwing an exception is the worst imaginable response.
Uh, run-time tests using C-style macros, much like assertions. Frankly, I would have been more impressed by some template/constexpr magic implementing compile-time tests.
You can't implement the assertions at compile time since they are predicates evaluated at runtime. This is also why it is a performance hit on the code. I chose to use C-style macros because it is easier to debug than templates.
Yes OLD stores the value of the variable before the execution of the DO.
This is because all of the virtual methods that have been overriden are visited in order to gather their assertions, but not execute their DO(). So while the assertions are being collected it also collects OLD() values which then can be tested at the called virtual method in its ENSURE() clause.
OLD is a complicated mechanism to implement in C++ because it requires saving current variables at the same time deferring the code to be executed.
An exception, by definition, is to enable recovery from externally imposed events in a well-defined program state.
The only useful, meaningful response to discovering a contract violation is termination. Throwing an exception is the worst imaginable response.