Jump to page: 1 2
Thread overview
struct initializer
Nov 29
Dom DiSc
Nov 29
Antonio
Nov 30
Dom DiSc
Nov 30
Dom DiSc
Nov 30
Dennis
Dec 01
Dom DiSc
Dec 01
kdevel
Nov 30
zjh
Dec 01
Dom DiSc
Dec 01
zjh
Dec 01
bomat
November 29
struct S { int a; int b; }

S s = { 5, 2 }; // works fine

S fun() { return { 5, 2 }; } // doesn't work :-(

S fun2() { S s = { 5, 2 }; return s; } // works but is ugly

struct S2 { int a; int b; this(int c, int d) { a=c; b=d; } }

S2 fun3() { return S2( 5, 2 ); } // works but requires explicit constructor

Is there a reason why the short form is not possible?
It's clearly an initialization of a new instance of a struct, and the requested type is unambigous (the return type of the function).

November 29

On Wednesday, 29 November 2023 at 16:38:36 UTC, Dom DiSc wrote:

>
struct S2 { int a; int b; this(int c, int d) { a=c; b=d; } }

S2 fun3() { return S2( 5, 2 ); } // works but requires explicit constructor

You can use this syntax without an explicit constructor:

struct S3 { int a; int b; }

S3 fun() { return S3(5, 2); }

The language spec calls this a struct literal. If you're using a new enough compiler, it even supports named arguments:

S3 fun2() { return S3(b: 2, a: 5); }
November 29
On Wednesday, 29 November 2023 at 16:48:09 UTC, Paul Backus wrote:
> ... it even supports named arguments:

- Witch version of DMD supports named arguments?  Is it an experimental compiler option?




November 29
On Wednesday, 29 November 2023 at 17:23:04 UTC, Antonio wrote:
> On Wednesday, 29 November 2023 at 16:48:09 UTC, Paul Backus wrote:
>> ... it even supports named arguments:
>
> - Witch version of DMD supports named arguments?  Is it an experimental compiler option?

I don't know what the earliest version is that supports it, but I know the example I posted works in 2.105. It doesn't require any compiler options.

Named arguments are still a work in progress, and there are some situations where they aren't available (for example, I don't think they work for templates yet). With struct literals, though, you shouldn't have any problems using them.
November 30

On Wednesday, 29 November 2023 at 16:48:09 UTC, Paul Backus wrote:

>

You can use this syntax without an explicit constructor:

struct S3 { int a; int b; }

S3 fun() { return S3(5, 2); }

The language spec calls this a struct literal

Ok, so we have

struct S { int a; int b; }

S s = S(5, 3); // works
s = S(6, 2); // works
S fun() { return S(5, 2); } // works
int fun2(S s2);
fun2(S(4,4)); // works

but

struct S { int a; int b; }

S s = { 5, 3 }; // works
s = { 6, 2 }; // doesn't work
S fun() { return { 5, 2 }; } // doesn't work
int fun2(S s2);
fun2(S(4,4)); // doesn't work

So, why supporting the (somewhat strange looking) version with curly backets at all?
It only works in one special place, so is simply overhead to remember.
Again a superfluous way to do the same - but only under specific circumstances.

I think a syntax should work either always or never.

November 30

Sorry, I meant

>
fun2({4, 4}); // doesn't work
November 30

On Thursday, 30 November 2023 at 07:21:29 UTC, Dom DiSc wrote:

>

So, why supporting the (somewhat strange looking) version with curly backets at all?
It only works in one special place, so is simply overhead to remember.
Again a superfluous way to do the same - but only under specific circumstances.

I think a syntax should work either always or never.

The syntax was inherited from C. The 'special place' is called initialization, and it's special because the target type of the initializer is known in advance, while normal expression assignments are analyzed bottom up. Since there is no typeof({10, 10}), struct initializers don't work as expressions.

C99 added Compound literals (S){.a = 10, .b = 20}, and with named arguments you can do the same in D: S(a: 10, b:20), and since the type name is included, they do work as standalone expressions.

Walter tried to deprecate the old struct initializer syntax:
https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1031.md

But it got some resistance, since {} initializers still have an advantage when you want to define an array of structs, and don't want to repeat the (potentially long) struct name for every entry.

Also note that even when {} is removed, there are still other special cases with initialization, for example with arrays:

void main()
{
    short[] a = [3: 10]; // ok
    a = [3: 10]; // cannot implicitly convert expression `[3:10]` of type `int[int]` to `short[]`
}
November 30

On Wednesday, 29 November 2023 at 16:38:36 UTC, Dom DiSc wrote:

> struct S { int a; int b; }
> S2 fun3() { return S2( 5, 2 ); }

Here,S2( 5, 2 ); violeit DRY principle.

December 01

On Thursday, 30 November 2023 at 14:10:35 UTC, zjh wrote:

>

On Wednesday, 29 November 2023 at 16:38:36 UTC, Dom DiSc wrote:

> struct S { int a; int b; }
> S2 fun3() { return S2( 5, 2 ); }

Here,S2( 5, 2 ); violeit DRY principle.

Yes. I think if we have the brackets form, it should be allowed here:

S Fun(){ return { 5, 2 }; }

This IS an initialization and the type is known. Requiring the repetition of the type is also here annoying.
So it is not a syntax reserved for initialization, but only for initialization with equals operator. I think this is inconsequent.
Either allow it for all initializations, or get rid of it, like DIP 1031 suggested.

December 01

On Thursday, 30 November 2023 at 12:15:04 UTC, Dennis wrote:

>

The syntax was inherited from C. The 'special place' is called initialization, and it's special because the target type of the initializer is known in advance

This is no different from S fun(){ return { 5, 2 }; } It creates a new instance of a struct, and the type is known in advance (it's the return type). So it's not an expression. But this place of initialization is not allowed. Therefor I think calling S s = { 5, 2 }; 'special' is justified.

« First   ‹ Prev
1 2