Invariants are useless the way they are defined

Jonathan M Davis jmdavisProg at gmx.com
Sun Aug 25 14:56:27 PDT 2013


On Sunday, August 25, 2013 14:16:28 deadalnix wrote:
> As they are defined now, invariant are plain useless. I find
> myself disabling them one by one in my code as soon as cases get
> outside simple trivia.
> 
> The problem is that invariant are checked at the beginning/end on
> public function calls. As a consequence, it is impossible to use
> any public method in an invariant.
> 
> For instance, just right now I did refactor a struct to use
> bitfields, in order to make it more compact. Now I have to remove
> the invariant as field access are now function calls.
> 
> Another typical situation is when you want to assert certain
> properties in a class hierarchy, where calling virtual method is
> part of the invariant check.
> 
> invariant should (and must to be useful) be inserted at callee
> point, when the callee isn't itself subject to invariant
> insertion, and around public memeber manipulation (when the
> manipulator isn't subject to invariant insertion).
> 
> Any other pattern it doomed to create infinite recursion for non
> trivial invariant checks.

What drives me nuts is the fact that it gets checked when opAssign is called 
(rather than just when exiting it). That makes it impossible to have a member 
in an invalid state (either through an init which has an invalid state similar 
to how floating point values due or because the object hasn't been initialized 
yet) and have an invariant. At present, emplace will blow up in your face if 
you try and have an invariant with such types. The result is that I almost 
never use invariant. It ends up working better to just create a private 
function which is the invariant and asserting explicitly in every function 
where you want the check, but most of the time, that's enough of a pain that 
the result is that it's just not checked.

Unfortunately, my enhancement request on that (not having the invariant called 
on entry to opAssign) was shot down, because there are some opAssigns which 
require that the previous state be valid rather than just replacing it (which 
means that what you really need is a way to declare an invariant but disable 
it in certain places).

- Jonathan M Davis


More information about the Digitalmars-d mailing list