Allow default constructors for structs

Steven Schveighoffer schveiguy at gmail.com
Fri Aug 30 19:11:59 UTC 2024


On Thursday, 29 August 2024 at 14:28:09 UTC, Ogi wrote:
> This has been discussed ad nauseam, so I’m skipping rationale. 
> Let’s just say that many users want this feature, especially 
> those who need C++ interop. Here’s how it can be implemented in 
> a non-problematic way.
>
> A struct with a default constructor can only be instantiated by 
> an [explicit] constructor call, following the same rules as a 
> struct with a disabled default constructor.

I dislike the requirement to explicitly construct. I don't see 
the drawback of implicit construction.

> ```D
> struct S {
>     this() {
>         writeln("S.this()");
>     }
> }
>
> void main {
>     S s; // error
>     S t = S(); // ok (constructed by calling `S.this()`)
>     S u = void; // ok (not `@safe`)
>     S v = S.init; // ok (may be a logically incorrect object)
>     S[3] a; // error
>     S[3] b = [S(), S(), S()]; // ok
> }
> ```

The array example is so bad...

> If any fields of an aggregate type are structs with default 
> constructors, all constructors of this type must initialize 
> them. If a default constructor is not defined, default 
> construction is disabled.
>
> ```D
> struct S {
>     this() { writeln("S.this()"); }
> }
>
> struct T {
>     S s;
>     // implicit `@disable this();`
> }
> ```

Why not implicit:

```d
this() {
    s = S();
}
```

> ```D
> struct U {
>     S s;
>     this(int x) {} // error: `s` must be initialized
>     this() { s = S(); }
> }
> class C {
>     S s;
>     this(int x) {} // error: `s` must be initialized
>     this() { s = S(); }
> }
>
> ```

Seems fine

But what happens in this case?

```d
struct S
{
    this(int) {}
}

S s; // ok?
```

Seems like if you want to *require* constructor calls when they 
are present, it should be consistent.

This is a different approach than what I posted 
[here](https://forum.dlang.org/post/onsftzijgkpjkpdbbzec@forum.dlang.org). I'm approaching it from the side of *hooking default initialization*, whereas you are approaching it from the side of *disallowing default initialization*.

Note that with the advent of editions, we can do whatever we want 
with semantics, and given that default constructors do not 
currently exist, keeping existing behavior when they are not 
present seems reasonable to me.

-Steve


More information about the dip.ideas mailing list