On 4/12/17 12:34 PM, Mathias Lang wrote:
On Wednesday, 12 April 2017 at 16:22:00 UTC, Lewis wrote:
I have to ask the newbie question, just to make sure we're not missing
anything obvious. Why can't we fix invariants so that they're
pay-for-what-you-use? In other words, is there a way we can make sure
_d_invariant is never called (or early-outs) for classes that don't
use invariants?
There's no newbie question :)
Sadly it is not possible. Consider the following hierarchy:
```
class Mother : Object { public int i; public void myFunction () {} }
class Daughter1 : Mother { invariant () { assert(i != 0); } }
class Daughter2 : Mother {}
```
The `Mother` class needs to insert invariant checks at the beginning and
the end of `myFunction` to account for the possibility of a derived
class defining invariant (here `Daughter1`). However those checks are
superfluous if no `invariant` is defined, as it's the case with
`Daughter2`.
However the base class cannot know this in advance (because it might be
in a library and already compiler, for example).
You can check the vtable address against the known Object.invariant address.
To explain further (no idea what the symbol names are, but you get the
idea):
executeInvariant(Object o)
{
static so = new Object; // has default invariant
if((&so.__invariant).funcptr != &(so.__invariant).funcptr)
// need to call invariant, not the default
o.__invariant();
}
I'm sure the compiler can do this without any indirections or virtual calls.
Better yet, just put null in the Object.invariant vtable entry. Then
it's really easy!
-Steve