Jump to page: 1 2
Thread overview
Allow default constructors for structs
Aug 29
Ogi
Aug 29
IchorDev
Aug 29
Ogi
Aug 30
monkyyy
Aug 30
Dukc
Aug 30
monkyyy
Aug 30
Dukc
Aug 30
Ogi
Aug 30
monkyyy
August 29

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 implicit constructor call, following the same rules as a struct with a disabled default constructor.

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
}

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.

struct S {
    this() { writeln("S.this()"); }
}

struct T {
    S s;
    // implicit `@disable this();`
}

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(); }
}

void main {
    T t1; // error: default construction is disabled
    T t2 = T(); // ditto
    U u = U(); // ok
    C c = new C(); // ok
}

Destroy.

August 29

Yes please!

August 29

On Thursday, 29 August 2024 at 14:28:09 UTC, Ogi wrote:

>

especially those who need C++ interop.

Yes, hello. Here I am. I had to manually write C++ constructor mangling to hack in default constructors for C++ interop! It SUCKED!

>

Here’s how it can be implemented in a non-problematic way.

A struct with a default constructor can only be instantiated by an implicit constructor call, following the same rules as a struct with a disabled default constructor.

Genius. This shouldn’t even need to become a DIP because it’s so genius.

August 29

On Thursday, 29 August 2024 at 14:28:09 UTC, Ogi wrote:

>

A struct with a default constructor can only be instantiated by an implicit constructor call

s/implicit/explicit

August 30

On Thursday, 29 August 2024 at 14:28:09 UTC, Ogi wrote:

>

struct T {
S s;
// implicit @disable this();
}

why? I just got bitten by nested structs being hard to init (with terrible error messages), why not just fix the problem?

August 30
monkyyy kirjoitti 30.8.2024 klo 14.11:
> On Thursday, 29 August 2024 at 14:28:09 UTC, Ogi wrote:
>> struct T {
>>     S s;
>>     // implicit `@disable this();`
>> }
> 
> why? I *just* got bitten by nested structs being hard to init (with terrible error messages), why not just fix the problem?

There is a reason. D is designed so that every type, except `noreturn`, has an `.init` value. It's supposed to be a value, not a function. This is why a struct cannot have a default constructor. If we break that pattern, then we run into some pretty strange situtions. For example, what would be the `.init` value of a static array of structs with a default constructor? What if the `.init` value of such a struct is used at CTFE? If the struct is a member of another struct, should the default constructor be called only once to determine `.init` value of the parent struct, or every time the parent struct is initialised?

However, I agree that structs (and unions) with context pointers are really annoying because they break that pattern of `.init` value for every type. Maybe it should be allowed to initialise nested structs with a null context.
August 30
On Friday, 30 August 2024 at 12:29:43 UTC, Dukc wrote:
> monkyyy kirjoitti 30.8.2024 klo 14.11:
>> On Thursday, 29 August 2024 at 14:28:09 UTC, Ogi wrote:
>>> struct T {
>>>     S s;
>>>     // implicit `@disable this();`
>>> }
>> 
>> why? I *just* got bitten by nested structs being hard to init (with terrible error messages), why not just fix the problem?
>
> There is a reason. D is designed so that every type, except `noreturn`, has an `.init` value. It's supposed to be a value, not a function. This is why a struct cannot have a default constructor. If we break that pattern, then we run into some pretty strange situtions. For example, what would be the `.init` value of a static array of structs with a default constructor? What if the `.init` value of such a struct is used at CTFE? If the struct is a member of another struct, should the default constructor be called only once to determine `.init` value of the parent struct, or every time the parent struct is initialised?
>
> However, I agree that structs (and unions) with context pointers are really annoying because they break that pattern of `.init` value for every type. Maybe it should be allowed to initialise nested structs with a null context.

.init sucks as a standard, I only ever use it as I have nothing else see my post about .zero (there is **not a standard**, int.init!=float.init, are ranges init even fixable? is nullable.init well defined? is sumtype.init?)

but this proposal does not maintain a .init "standard"

>>>S v = S.init; // ok (may be a logically incorrect object)
August 30
monkyyy kirjoitti 30.8.2024 klo 15.45:
> 
> .init sucks as a standard, I only ever use it as I have nothing else see my post about .zero (there is **not a standard**, int.init!=float.init, are ranges init even fixable? is nullable.init well defined? is sumtype.init?)
> 
> but this proposal does not maintain a .init "standard"
>

But if it's really going to break the standard, it needs to answer how to deal with the resulting complications.

August 30

On Friday, 30 August 2024 at 12:45:27 UTC, monkyyy wrote:

>

but this proposal does not maintain a .init "standard"

> > >

S v = S.init; // ok (may be a logically incorrect object)

Using .init to initialize a struct with a disabled default constructor is well defined and allowed even in @safe code. This proposal doesn’t change anything in this regard.

August 30

On Friday, 30 August 2024 at 16:17:08 UTC, Ogi wrote:

>

On Friday, 30 August 2024 at 12:45:27 UTC, monkyyy wrote:

>

but this proposal does not maintain a .init "standard"

> > >

S v = S.init; // ok (may be a logically incorrect object)

Using .init to initialize a struct with a disabled default constructor is well defined and allowed even in @safe code. This proposal doesn’t change anything in this regard.

... no its poorly defined

>

If there is a default constructor for an object, it may produce a different value.

It may not be c's "undefined behavior ^tm" but it is undefined; the spec of .init may as well say ".init will exist, and heres a bunch of ways its useless"

and my critism is the post above that one

« First   ‹ Prev
1 2