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