www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Array operations, dynamic arrays and length

reply "ixid" <adamsibson hotmail.com> writes:
	int[] a = [1,1,1,1];
	int[] b = [1,1,1,1];
	int[] c;

	c[] = a[] - b[];

	c.writeln;

This outputs []. This feels wrong, it feels like something that 
should have exploded or set the length to 4. If the lengths of a 
and b are mismatched it throws an exception. It also throws an 
exception if a dynamic array is longer or a static array is not 
the same length but is happy when a dynamic array is shorter. Is 
this intended behaviour and if so why?
Jun 30 2015
next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 30 June 2015 at 22:37:34 UTC, ixid wrote:
 	int[] a = [1,1,1,1];
 	int[] b = [1,1,1,1];
 	int[] c;

 	c[] = a[] - b[];

 	c.writeln;

 This outputs []. This feels wrong, it feels like something that 
 should have exploded or set the length to 4. If the lengths of 
 a and b are mismatched it throws an exception. It also throws 
 an exception if a dynamic array is longer or a static array is 
 not the same length but is happy when a dynamic array is 
 shorter. Is this intended behaviour and if so why?
Yes, clearly a bug. Please open a bug report at https://issues.dlang.org/
Jul 01 2015
prev sibling next sibling parent reply "Alex Parrill" <initrd.gz gmail.com> writes:
On Tuesday, 30 June 2015 at 22:37:34 UTC, ixid wrote:
 	int[] a = [1,1,1,1];
 	int[] b = [1,1,1,1];
 	int[] c;

 	c[] = a[] - b[];

 	c.writeln;

 This outputs []. This feels wrong, it feels like something that 
 should have exploded or set the length to 4. If the lengths of 
 a and b are mismatched it throws an exception. It also throws 
 an exception if a dynamic array is longer or a static array is 
 not the same length but is happy when a dynamic array is 
 shorter. Is this intended behaviour and if so why?
I don't think this is a bug. Since you don't initialize `c` to anything, it defaults to an empty slice. Array [] operations apply to each element of a slice, but `c` doesn't have any elements, so it does nothing. Change `int[] c;` to `int[] c = new int[4];` and it works.
Jul 01 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Wednesday, 1 July 2015 at 19:09:36 UTC, Alex Parrill wrote:
 I don't think this is a bug.

 Since you don't initialize `c` to anything, it defaults to an 
 empty slice. Array [] operations apply to each element of a 
 slice, but `c` doesn't have any elements, so it does nothing.
I _do_ think it's a bug. Compare: import std.stdio; void main() { int[] a = [1,1,1,1]; int[] b = [1,1,1,1]; int[] c; int[2] d; c[] = a[] - b[]; // works c.writeln; // [] d[] = a[] - b[]; // works d.writeln; // [0, 0] d[] = a[]; // throws! // object.Error (0): Array lengths don't match for copy: 4 != 2 } So, in the case of subtraction, it assigns only as many elements as the destination has, but for direct assignment, it throws an error. This is clearly inconsistent.
Jul 01 2015
parent reply "J Miller" <foo bar.com> writes:
On Wednesday, 1 July 2015 at 21:15:13 UTC, Marc Schütz wrote:
 On Wednesday, 1 July 2015 at 19:09:36 UTC, Alex Parrill wrote:
 I don't think this is a bug.

 Since you don't initialize `c` to anything, it defaults to an 
 empty slice. Array [] operations apply to each element of a 
 slice, but `c` doesn't have any elements, so it does nothing.
I _do_ think it's a bug. Compare: import std.stdio; void main() { int[] a = [1,1,1,1]; int[] b = [1,1,1,1]; int[] c; int[2] d; c[] = a[] - b[]; // works c.writeln; // [] d[] = a[] - b[]; // works d.writeln; // [0, 0] d[] = a[]; // throws! // object.Error (0): Array lengths don't match for copy: 4 != 2 } So, in the case of subtraction, it assigns only as many elements as the destination has, but for direct assignment, it throws an error. This is clearly inconsistent.
Bug. "c[] = a[] <op> b[]" produces "[]" for operators "-" and "/", but "object.Error (0): Array lengths don't match for vector operation: 0 != 4" for operators "+" and "*". Wat. Oh, and to make things really confusing, "auto e = a[] - b[]" and "int[] e = a[] - b[]" both cause "Error: array operation a[] - b[] without destination memory not allowed". Using dmd 2.067.0.
Jul 01 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/1/15 8:36 PM, J Miller wrote:

 Oh, and to make things really confusing, "auto e = a[] - b[]" and "int[]
 e = a[] - b[]" both cause "Error: array operation a[] - b[] without
 destination memory not allowed".

 Using dmd 2.067.0.
This is not a bug. You need to allocate memory before you can write to it. Automatic allocation doesn't happen in D. -Steve
Jul 02 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Thursday, 2 July 2015 at 10:48:56 UTC, Steven Schveighoffer 
wrote:
 On 7/1/15 8:36 PM, J Miller wrote:

 Oh, and to make things really confusing, "auto e = a[] - b[]" 
 and "int[]
 e = a[] - b[]" both cause "Error: array operation a[] - b[] 
 without
 destination memory not allowed".

 Using dmd 2.067.0.
This is not a bug. You need to allocate memory before you can write to it. Automatic allocation doesn't happen in D.
This particular part works as intended, but the other things _are_ buggy.
Jul 02 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/2/15 8:21 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:
 On Thursday, 2 July 2015 at 10:48:56 UTC, Steven Schveighoffer wrote:
 On 7/1/15 8:36 PM, J Miller wrote:

 Oh, and to make things really confusing, "auto e = a[] - b[]" and "int[]
 e = a[] - b[]" both cause "Error: array operation a[] - b[] without
 destination memory not allowed".

 Using dmd 2.067.0.
This is not a bug. You need to allocate memory before you can write to it. Automatic allocation doesn't happen in D.
This particular part works as intended, but the other things _are_ buggy.
Right, my point was to address an obvious misconception on how these statements work. Other languages happily will allocate a new array in such cases, D does not. -Steve
Jul 02 2015
parent reply "J Miller" <foo bar.com> writes:
On Thursday, 2 July 2015 at 12:59:03 UTC, Steven Schveighoffer 
wrote:
 On 7/2/15 8:21 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= 
 <schuetzm gmx.net>" wrote:
 On Thursday, 2 July 2015 at 10:48:56 UTC, Steven Schveighoffer 
 wrote:
 On 7/1/15 8:36 PM, J Miller wrote:

 Oh, and to make things really confusing, "auto e = a[] - 
 b[]" and "int[]
 e = a[] - b[]" both cause "Error: array operation a[] - b[] 
 without
 destination memory not allowed".

 Using dmd 2.067.0.
This is not a bug. You need to allocate memory before you can write to it. Automatic allocation doesn't happen in D.
This particular part works as intended, but the other things _are_ buggy.
Right, my point was to address an obvious misconception on how these statements work. Other languages happily will allocate a new array in such cases, D does not. -Steve
I knew that automatic allocation doesn't happen, but I'm confused by the fact if you explicitly declare "c" with "int[] c;" and then assign "c[] = a[] * b[]", versus using "auto c = a[] * b[]", you get two different errors (array length mismatch vs no destination memory).
Jul 02 2015
parent "jmh530" <john.michael.hall gmail.com> writes:
On Thursday, 2 July 2015 at 19:27:57 UTC, J Miller wrote:
 I knew that automatic allocation doesn't happen, but I'm 
 confused by the fact if you explicitly declare "c" with "int[] 
 c;" and then assign "c[] = a[] * b[]", versus using "auto c = 
 a[] * b[]", you get two different errors (array length mismatch 
 vs no destination memory).
I find it confusing as well. For me it's about consistency of syntax. For instance, auto z = x+y works with numeric types, but the equivalent you use for arrays doesn't work. It just means one more thing to remember.
Jul 04 2015
prev sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
https://issues.dlang.org/show_bug.cgi?id=14759
Jul 02 2015