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

Jonathan M Davis jmdavisProg at gmx.com
Fri Oct 12 01:20:24 PDT 2012


On Friday, October 12, 2012 10:09:22 monarch_dodra wrote:
> When you declare s void, you are supposed to memcpy .init over it
> manually, or call emplace (which does the same thing + more).

If that's what you're "supposed" to do, it's only because opAssign is annoying 
enough to check its invariant. Without the invariant, that's not something 
that would normally make sense to do. And it's _not_ what you do with a built-
in type.

int i = void;
i = 5;

is perfectly legal. I see no reason why

S s = void;
s = S(17);

shouldn't be legal as well. And it _is_ legal, except when you're unlucky 
enough to need to define an opAssign for S, because then that'll blow up in 
your face if you have an invariant.

And because the _only_ reason that using memcpy or emplace would be necessary 
(or really make any sense at all) is to work around the fact that the 
invariant is called before opAssign, that means that you have to contort your 
code specifically to make it work in non-release mode, making it _less_ efficient 
in release mode. And since usually the point of initializing to void is to 
gain extra efficiency, this is entirely counterproductive.

I'd argue that _any_ code which is specifically doing emplace or memcpy because 
it initialized to void is probably a bad idea. If that's what it needs to do, 
it shouldn't have been initialized to void in the first place. And if it's 
because of the invariant, then it makes way more sense to ditch the invariant 
then use emplace like that.

Really, I think that it's a bad design decision to require that the invariant 
be called before opAssign. It does _not_ play nice with some of D's other 
features, and the result is likely to be that invariants get used less, 
meaning that code is more likely to be buggy.

- Jonathan M Davis


More information about the Digitalmars-d mailing list