struct: default construction or lazy initialization.

kinke via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Feb 1 15:24:27 PST 2017


On Wednesday, 1 February 2017 at 23:02:11 UTC, bitwise wrote:
> On Wednesday, 1 February 2017 at 01:52:40 UTC, Adam D. Ruppe 
> wrote:
>> On Wednesday, 1 February 2017 at 00:43:39 UTC, bitwise wrote:
>>> Container!int c; // = Container!int() -> can't do this.
>>
>> Can you live with
>>
>> Container!int c = Container!int.create();
>>
>> because D supports that and can force the issue with `@disable 
>> this();` which causes compilation to fail any place where it 
>> isn't explicitly initialized.
>
> I suppose this works, but to be honest, I wouldn't use it.

I rather wouldn't have to live with this limitation as well. The 
problem is that if my struct T can only be correctly initialized 
via static factory, all aggregates containing a field of type T 
(directly or indirectly!) will then have to have a static factory 
as well => no real RAII.

> The current behavior doesn't even really make sense.
>
> Example:
>
> struct S  {
>     // this(){}
>     this(Args...)(auto ref Args args) { writeln("ctor"); }
>     ~this() { writeln("dtor"); }
> }
>
> void foo(Args...)(auto ref Args args) { writeln("foo"); }
>
> int main(string[] argv) {
>     S s;
>     S s2 = S();
>     foo();
>     return 0;
> }
>
> outputs:
>   foo
>   dtor
>   dtor
>
> I would expect that I could at least have this() invoked  for 
> 's2', but I can't even declare it at all. So while 'S()' looks 
> like a constructor call, it doesn't call one. Instead, the 
> current behavior forces explicit initialization of objects, 
> pointless boilerplate, or unorthodox/unreliable workarounds.
>
> Even more confusingly, the above example prints "foo" but not 
> "ctor", because calling variadic functions with no arguments is 
> fine - except for constructors.
>
> Finally, destructors are currently called on objects which were 
> never constructed. You can't even call what's going on with 
> structs RAII at this point.

It's not that bad. D just doesn't support a default ctor for 
structs at all and simply initializes each instance with T.init. 
Your `s2` initialization is most likely seen as explicit default 
initialization (again with T.init). Destructing both instances is 
exactly what should happen.

Can anyone point to the rationale for not supporting default 
constructors for structs? It prevents true RAII and hinders C++ 
interop.


More information about the Digitalmars-d-learn mailing list