What is the case against a struct post-blit default constructor?

monarch_dodra monarchdodra at gmail.com
Thu Oct 11 22:53:09 PDT 2012


On Thursday, 11 October 2012 at 22:05:34 UTC, Jonathan M Davis
wrote:
> On Friday, October 12, 2012 01:20:44 Dmitry Olshansky wrote:
>> > 
>> > This sounds more like a limitation of invariants, rather 
>> > than a problem
>> > with .init. You make (imo) a valid point.
>> > 
>> > Would it be complicated for opAssign to first check 
>> > memcmp(this,
>> > T.init), and only do entry invariant check if the comparison 
>> > fails?
>> > 
>> > Potentially ditto on exit.
>> 
>> With your rule T.init is a valid state. AFAICT in Jonathan's 
>> example it
>> isn't.
>
> Yeah. All that's required is that you outright skip the call to 
> the invariant
> before calling opAssign. It _does_ mean special casing 
> opAssign, but I don't
> see that as a problem. I don't understand why it matters 
> whether the object is
> valid before it's assigned to. Presumably, you're completely 
> replacing its
> state, and regardless of what you actually do in the function, 
> it would still
> need to be valid afterwards. So, it seems perfectly fine to me 
> to just skip
> calling the variant before calling opAssign, but Walter was 
> against it. His
> comment on the bug ( 
> http://d.puremagic.com/issues/show_bug.cgi?id=5058 )
> indicated that he thought that init should always be in a valid 
> state, but
> since NaN and null are invalid states, I see no reason that a 
> struct's init
> value can't be an invalid state. It can be copied and passed 
> around just fine.
> It just wouldn't pass its invariant if you tried to call a 
> function on it
> before assigning it a valid value.
>
> - Jonathan M Davis

Yes, as answered, opAssign may do things to this, such as
dealocate a payload, reduce a ref counter, or who knows what.

As a matter of fact, there was a bug in emplace about that I
recently fixed.

My rational for skipping the test *ONLY* if "this == .init" is
that .init is supposed to mean not yet fully initialized. This
would make code such as:

T t = t.init; //Not yet ready for use.
                 //Attempt to use will assert the invariant
...
t = T(5); //Initialize it later. Don't check invariant on entry
...
//Use t and check invariants every time.
...
t = t.init; //De-initialization, Don't check invariant on exit.
               //Future attempt for use will assert the invariant

I'd also do the same for destructor entry: The language already
states that .init SHOULD be a valid destructible state.


More information about the Digitalmars-d mailing list