Thread overview
Initialise dynamic array in array of structures
Jun 21, 2016
Paul
Jun 21, 2016
ketmar
Jun 21, 2016
cym13
Jun 21, 2016
ketmar
Jun 22, 2016
Paul
Jun 22, 2016
ketmar
Jun 22, 2016
cym13
Jun 22, 2016
ketmar
Jun 22, 2016
ketmar
June 21, 2016
Given these structures and declaration:

struct CoordList{
        int x, y;
}

struct Part{
	int x, y;
	CoordList[] coords;
	int nextNode, prevNode;
	string nextEnter, prevEnter;
}

Part[10] trackTemplates;


Can someone please tell me why I can't initialise Part[0].coords like this:

trackTemplates[0].coords = [ {0, 9}, {1, 1}, {3, 6} ];

but I can do this:

CoordList[] temp = [ {0, 9}, {1, 1}, {3, 6} ];
trackTemplates[0].coords = temp;

Many thanks!




June 21, 2016
trackTemplates[0].coords = [ CoordList(0, 9), CoordList(1, 1), CoordList(3, 6) ];
June 21, 2016
On Tuesday, 21 June 2016 at 19:15:56 UTC, Paul wrote:
> Given these structures and declaration:
>
> struct CoordList{
>         int x, y;
> }
>
> struct Part{
> 	int x, y;
> 	CoordList[] coords;
> 	int nextNode, prevNode;
> 	string nextEnter, prevEnter;
> }
>
> Part[10] trackTemplates;
>
>
> Can someone please tell me why I can't initialise Part[0].coords like this:
>
> trackTemplates[0].coords = [ {0, 9}, {1, 1}, {3, 6} ];
>
> but I can do this:
>
> CoordList[] temp = [ {0, 9}, {1, 1}, {3, 6} ];
> trackTemplates[0].coords = temp;
>
> Many thanks!

My take is that “CoordList[] temp = [{0, 9}, {1, 1}, {3, 6}];” is initialization because you're setting the value when defining it but “trackTemplates[0].coords = [{0, 9}, {1, 1}, {3, 6}];” is an assignment so the compiler can infer as much and doesn't understand that each of those list of values are really CoordLists. For example “    trackTemplates[0].coords = [CoordList(0, 9), CoordList(1, 1), CoordList(3, 6)];” would have worked as expected.

June 21, 2016
On Tuesday, 21 June 2016 at 19:33:31 UTC, cym13 wrote:
i would want him to figure that by himself, tbh. just to remember that "{}" struct initialization is BAD. ;-)
June 22, 2016
On Tuesday, 21 June 2016 at 19:33:31 UTC, cym13 wrote:
... but “trackTemplates[0].coords = [{0, 9}, {1, 1},
> {3, 6}];” is an assignment so the compiler can infer as much and doesn't understand that each of those list of values are really CoordLists.

I see, but it seems a bit strange given that they are being assigned to .coords[] which is already defined as of type CoordList.

> trackTemplates[0].coords = [CoordList(0, 9), CoordList(1, 1), CoordList(3, 6)];” would have worked as expected.

I'd want to avoid this wordy explicit way as the list can extend to several hundred pairs. Most likely I need a better way to store the information.

@ketmar:

Why is initialisation via {} bad (in simple terms please :D)? I noticed while working on this bit of code that I could initialise simple struct variables with {} but couldn't do the same with an array of structs. I guess this is for the same or similar reason to the above.

Thanks both for the help.
June 22, 2016
On Wednesday, 22 June 2016 at 06:43:12 UTC, Paul wrote:
> Why is initialisation via {} bad (in simple terms please :D)?

first, it is buggy. i.e. it doesn't always call postblit[1]. second, it's syntax is the same as the syntax of argument-less lambda, which makes it context-dependent -- so reader has to make some mental efforts to find out if it is really lambda or struct initialization.

for me, it is enough to see it as bad. and for some other people too. ;-)


[1] https://issues.dlang.org/show_bug.cgi?id=16146
June 22, 2016
On Wednesday, 22 June 2016 at 08:06:26 UTC, ketmar wrote:
> On Wednesday, 22 June 2016 at 06:43:12 UTC, Paul wrote:
>> Why is initialisation via {} bad (in simple terms please :D)?
>
> first, it is buggy. i.e. it doesn't always call postblit[1]. second, it's syntax is the same as the syntax of argument-less lambda, which makes it context-dependent -- so reader has to make some mental efforts to find out if it is really lambda or struct initialization.
>
> for me, it is enough to see it as bad. and for some other people too. ;-)
>
>
> [1] https://issues.dlang.org/show_bug.cgi?id=16146

On the other hand I don't see why you'd expect {} to call postblit at
all.  Postblit is meant for copy construction while here (with {})
there is no copy, just an initialization. And actually the "verbose"
way doesn't call postblit either:


import std.stdio;

struct Coord {
    int x, y;

    this(this) { writeln("Postblit (", x, ",", y, ")"); }
}

void main(string[] args) {
    writeln("Building a");
    Coord a = {1, 3};

    writeln("Building b");
    Coord b = Coord(4, 2);
}

/*
 (fcn) sym._Dmain 78
; var int local_14h @ ebp-0x14
; var int local_10h @ ebp-0x10
; var int local_ch @ ebp-0xc
; var int local_8h @ ebp-0x8
; var int local_4h @ ebp-0x4
; DATA XREF from 0x08078f13 (sym.main)
0x080786e0   push ebp
0x080786e1   mov ebp, esp
0x080786e3   sub esp, 0x14
0x080786e6   mov dword [ebp - local_14h], ebx
0x080786e9   mov ecx, str.Building_a
0x080786ee   mov eax, 0xa
0x080786f3   push ecx
0x080786f4   push eax
0x080786f5   call sym._D3std5stdio16__T7writelnTAyaZ7writelnFNfAyaZv
; Construction of 'a'
0x080786fa   mov dword [ebp - local_10h], 1
0x08078701   mov dword [ebp - local_ch], 3
0x08078708   mov edx, str.Building_b
0x0807870d   mov ebx, 0xa
0x08078712   push edx
0x08078713   push ebx
0x08078714   call sym._D3std5stdio16__T7writelnTAyaZ7writelnFNfAyaZv
; Construction of 'b'
0x08078719   mov dword [ebp - local_8h], 4
0x08078720   mov dword [ebp - local_4h], 2
0x08078727   xor eax, eax
0x08078729   mov ebx, dword [ebp - local_14h]
0x0807872c   leave
0x0807872d   ret
*/

No postblit.

June 22, 2016
On Wednesday, 22 June 2016 at 09:27:01 UTC, cym13 wrote:
> On the other hand I don't see why you'd expect {} to call postblit at
> all.

'cause it essentially makes a copy. i gave the sample in bugreport. it worth me a hour of debugging to find why my refcounted struct keep crashing with invalid counter.
June 22, 2016
On Wednesday, 22 June 2016 at 09:27:01 UTC, cym13 wrote:

what i meant is that "{}" should be fully equivalent to "Struct()" ctor in terms of calling postblits, and it isn't.