DIP 1006 - Preliminary Review Round 1

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Thu Apr 27 12:31:07 PDT 2017


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


More information about the Digitalmars-d mailing list