www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - multi-dimensional dynamic arrays

reply Jay Norwood <jayn prismnet.com> writes:
Strange to me that this compiles, since I would expect there to 
be some C-like limitation on the position of the unspecified 
dimension.  Is allowing this somehow useful?

int[1][][1] ub;
writeln("ub",ub);
Feb 18 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, February 19, 2016 06:54:51 Jay Norwood via Digitalmars-d-learn wrote:
 Strange to me that this compiles, since I would expect there to
 be some C-like limitation on the position of the unspecified
 dimension.  Is allowing this somehow useful?

 int[1][][1] ub;
 writeln("ub",ub);
You can have dynamic arrays of static arrays. In this case, you have a static of dynamic arrays of static arrays. Alternatively, you could do something like auto arr = new int[1][](5); which would be a dynamic array of length 5 which holds static arrays of length 1. Or you could do something really wonky like auto arr = new int[][2][](5); which would be a dynamic array of length 5 which holds static arrays of length 2 which hold dynamic arrays which are null. All kinds of wacky combinations are possible. Now, are they _useful_? Well, that's another question entirely. Personally, I wouldn't use constructs like that, because they're too weird and too easy to screw up, but it wouldn't surprise me if someone at some point found a use for them. Personally, I tend to dislike even using multidimensional static arrays, because it's so easy to confuse the dimensions. e.g. int[5][3] arr; assert(arr.length == 3); assert(arr[0].length == 5); And the more complicated the array declaration, the more likely it is that you're going to screw it up - either in how it's declared or in how it's accessed. But the type system will let you do all kinds of crazy combinations if you really want to. - Jonathan M Davis
Feb 18 2016
parent reply Jay Norwood <jayn prismnet.com> writes:
On Friday, 19 February 2016 at 07:59:29 UTC, Jonathan M Davis 
wrote:
 .. Or you could do something really wonky like

     auto arr = new int[][2][](5);

 which would be a dynamic array of length 5 which holds static 
 arrays of length 2 which hold dynamic arrays which are null.
In my case, int [1][][1] ub;, there is only one dynamic dimension, but if I try to use .length to change the length, ub.length = 3, the compiler doesn't like that. int[1][][1] ubb; ubb.length = 3; src\app.d(13,5): Error: constant ubb.length is not an lvalue dmd failed with exit code 1. So, is there some supported syntax to set the length of the internal dimension, or to append to it?
Feb 19 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/19/16 8:53 AM, Jay Norwood wrote:
 On Friday, 19 February 2016 at 07:59:29 UTC, Jonathan M Davis wrote:
 .. Or you could do something really wonky like

     auto arr = new int[][2][](5);

 which would be a dynamic array of length 5 which holds static arrays
 of length 2 which hold dynamic arrays which are null.
In my case, int [1][][1] ub;, there is only one dynamic dimension, but if I try to use .length to change the length, ub.length = 3, the compiler doesn't like that.
Try ub[0].length = 3. You are trying to change the length on one of the static arrays. If you had more than 1 as a static dimension, then you would have to change the length of *each* of the elements. Arrays in D, are actually quite simple. Any time you see: T[] It's a dynamic array of T. Any time you see: T[N] Where N is a compile-time integer, it's a static array of T. So dissecting your type: int[1][][1] So the outer-most T is int[1][]. You have a single instance of this, in a static array. At the next level, T is int[1], where you have a dynamic array of these. Finally, at the 3rd level, T is int, you have a single element in a static array of int. -Steve
Feb 19 2016
parent Jay Norwood <jayn prismnet.com> writes:
On Friday, 19 February 2016 at 14:26:25 UTC, Steven Schveighoffer 
wrote:
 Try ub[0].length = 3. You are trying to change the length on 
 one of the static arrays.
yes, right these compile. I was surpised it wouldn't accept the append with just an int. int[1][][1] ubb; ubb[0].length = 3; ubb[0] ~= [5];
 If you had more than 1 as a static dimension, then you would 
 have to change the length of *each* of the elements.

 Arrays in D, are actually quite simple. Any time you see:

 T[]

 It's a dynamic array of T. Any time you see:

 T[N]

 Where N is a compile-time integer, it's a static array of T.

 So dissecting your type:

 int[1][][1]

 So the outer-most T is int[1][]. You have a single instance of 
 this, in a static array.

 At the next level, T is int[1], where you have a dynamic array 
 of these.

 Finally, at the 3rd level, T is int, you have a single element 
 in a static array of int.

 -Steve
Feb 19 2016