Automatic precondition generation (Was: Re: Automatic invariant generation)

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Sat Jul 8 11:01:18 PDT 2017


On 07.07.2017 16:17, Jonathan M Davis via Digitalmars-d wrote:
> On Friday, July 7, 2017 1:38:13 PM MDT Stefan Koch via Digitalmars-d wrote:
>> On Friday, 7 July 2017 at 13:34:20 UTC, Steven Schveighoffer
>>
>> wrote:
>>> On 7/7/17 4:21 AM, Nicholas Wilson wrote:
>>>> The compiler seems to inset an `assert(this !is null, "null
>>>> this");` into my struct.
>>>> which is for all intents and purposes.
>>>> struct Foo {
>>>>
>>>>       Bar b;
>>>>
>>>> }
>>>>
>>>> struct Bar {
>>>>
>>>>       void* ptr;
>>>>
>>>> }
>>>
>>> What? When is this invariant called? I've never heard of a
>>> hidden invariant being added to structs, structs are supposed
>>> to be free of such things.
>>>
>>> I would call such a thing a bug.
>>>
>>> -Steve
>>
>> It was added because someone VIP demanded it I guess.
>> you can see the assert being added using -vcg-ast ;)
> 
> What does it even do? I don't see how it makes any sense for _anything_ to
> have an invariant if it's not explicitly declared.

It is not an implicit invariant, it is an implicit precondition of a 
member function. (The 'this' reference is not part of the state, it is a 
function argument.)


> And honestly, I'm of the
> opinion that invariants with structs are borderline useless, because they're
> run even before opAssign, meaning that if you ever need to use = void;

A struct that has public methods that can accept an uninitialized 
instance does not have an invariant.
That does not mean invariants are useless for structs in general.

> or use emplace,

Why would the invariant be called if you use emplace? There are no 
public member functions involved.

> then you're screwed if you have an invariant, because it's
> bound to fail due to the object not having been initialized previously. > Unfortunately, I couldn't get Walter to agree that it made sense to 
not call
> the invariant prior to opAssign being called

It does not always make sense, and when it does make sense, it is not 
limited to opAssign, so maybe we can have an explicit way to disable 
invariant calls for member functions that do not rely on the object 
invariant. (For non-operator overloads there is an obvious workaround: 
just forward to a private member function using UFCS.)

> - which is why SysTime no
> longer has an invariant (it was blowing up in people's code due to emplace
> IIRC).

The only way this can be a problem is if they emplace a state that does 
not satisfy the invariant and then call opAssign. Was your invariant 
satisfied in the init state?

> As such, it seems that much more stupid for structs to get any kind
> fo invariant automatically.
> 
> - Jonathan M Davis
> 

That's not what is happening though.


More information about the Digitalmars-d mailing list