Structs are Not Plain: A call for empty struct constructors

FeepingCreature feepingcreature at gmail.com
Fri Sep 20 05:58:05 UTC 2019


On Friday, 20 September 2019 at 04:42:51 UTC, Max Samukha wrote:
> On Thursday, 19 September 2019 at 20:25:53 UTC, Jonathan M 
> Davis wrote:
> It has to do
>> with how D was designed with the idea that every type has an 
>> init value which is known at compile time, and various 
>> operations rely on being able to simply blit that init value.
>
> We understand the rationale behind the design. The point is 
> that the idea has never worked. If you define a destructor, you 
> most certainly want the object to be non-trivially initialized 
> at run time. New instances of
> that type, even "branded" with .init, are NOT initialized - 
> they are in an invalid state. That is why almost every D struct 
> with a destructor is compelled to implement those 
> opCall/external constructor/lazy initialization hacks.

This is correct. Around more complex types, the blittability of 
"init" has always been a polite fiction at best, a schizoid 
inconsistency at worst. Consider the existence of @disable this, 
consider that structs can have invariants, which would be 
completely useless if it had to apply to init - non-zero, 
non-null, non-empty, practically every invariant used in practice 
is violated in the init state. We put all this functionality on 
struct, when the simplest of it has already broken the POD myth.

This is not a new thing. The language has been like this for 
years. This is not a fight - if there ever was a fight, POD has 
lost. Phobos is littered with the workarounds of bugs that stem 
from this confusion. I think it's time to give up and say "yeah, 
struct .init exists, don't call any methods on it, be extremely 
careful to dispose of it, preferably just store it in a union 
field so the broken destructor doesn't get run by accident, it 
sucks but what can you do." Doing it properly would require 
explicit lifetime control, but we're not gonna get that any time 
soon anyway.

I'm not saying `this()` in a struct isn't broken. I'm saying it's 
not any worse broken than all these other broken things involving 
structs that we've already learnt to live with over the years, 
and in the meantime its absence is making code awkward for no 
realistic benefit.


More information about the Digitalmars-d mailing list