Andrzej Krzemienski wrote:
Let's introduce a new term: "effective invariant": this is a constraint on object's state much as "invariant". It determines what values an object can assume in a program where programmers adhere to the important principles that are necessary for programs to be correct. We can list some of them:
* Destructors do not throw exceptions, even if they fail to release resources
* Objects that threw from the operation with basic exception safety, which does not guarantee any other special behavior on exception, are never read: they are either destroyed or reset,
* Objects that are moved from, unless they explicitly guarantee something more, are only destroyed or reset.
"Effective invariants" have been tried before, and abandoned each time. This is basically the notion of "singular values", also known affectionately as "zombie objects". The most famous instance is probably two-phase construction, but signaling NaNs are another example. The idea is that these singular zombies "never occur" in the mythical correct program, so it's fine to make accesses to them undefined behavior. Typically, after a decade or so of experience, "never" is determined to occur much more frequently than previously thought, and the idea is abandoned, until its next discoverer. There are two main problems with this school of thought: one, creating a dormant zombie object is the worst possible thing that can happen in a program, because the "undefined behavior" can occur much later in a context far removed from the one that caused the error. Two, abiding by the rules that govern the supposedly correct programs is too cumbersome and there's no enforcement and no immediate feedback (compile- or run time) when they are broken.