Thread overview
Dynamic multidimensional arrays
Jul 05, 2011
Bellum
Jul 05, 2011
Jonathan M Davis
Jul 05, 2011
Trass3r
Jul 05, 2011
Jonathan M Davis
Jul 05, 2011
Jonathan M Davis
Jul 05, 2011
bearophile
Jul 05, 2011
Bellum
July 05, 2011
Can anyone point me in the right direction for doing something like this in D:

    char[][] anArray;
    int rows, cols;

    ...

    anArray = new char[rows][cols];

It isn't possible in this way because "rows cannot be read at compile time", which seems to me to be the point of dynamic arrays. :P
July 05, 2011
On 2011-07-04 23:42, Bellum wrote:
> Can anyone point me in the right direction for doing something like this in D:
> 
>      char[][] anArray;
>      int rows, cols;
> 
>      ...
> 
>      anArray = new char[rows][cols];
> 
> It isn't possible in this way because "rows cannot be read at compile time", which seems to me to be the point of dynamic arrays. :P

auto anArray = new char[][](rows, cols);

Putting the numbers directly in the brackets tries to create a static array once you get beyond the first dimension. So,

auto anArary = new char[4][5];

would create a dynamic array of length for with elements which are static arrays of length 5. If you want it to by dynamic all the way, you need to put the dimensions in the parens like above. Personally, I _never_ put them in the brackets, even when the dynamic array has just one dimension. It's just simpler to always put them in the parens and not worry about it.

- Jonathan M Davis
July 05, 2011
On 2011-07-04 23:56, Jonathan M Davis wrote:
> On 2011-07-04 23:42, Bellum wrote:
> > Can anyone point me in the right direction for doing something like this
> > 
> > in D:
> >      char[][] anArray;
> >      int rows, cols;
> > 
> >      ...
> > 
> >      anArray = new char[rows][cols];
> > 
> > It isn't possible in this way because "rows cannot be read at compile time", which seems to me to be the point of dynamic arrays. :P
> 
> auto anArray = new char[][](rows, cols);
> 
> Putting the numbers directly in the brackets tries to create a static array once you get beyond the first dimension. So,
> 
> auto anArary = new char[4][5];
> 
> would create a dynamic array of length for with elements which are static arrays of length 5. If you want it to by dynamic all the way, you need to put the dimensions in the parens like above. Personally, I _never_ put them in the brackets, even when the dynamic array has just one dimension. It's just simpler to always put them in the parens and not worry about it.

Correction,

auto anArray = new char[4][5];

would create a dynamic array of length 5 of static arrays with length 4, though

auto anArray = new char[][](4, 5);

does create a dynamic array of length 4 of dynamic arrays of length 5. It quickly gets confusing when dealing with dimensions and static arrays IMHO.

- Jonathan M Davis
July 05, 2011
Jonathan M Davis Wrote:

> It quickly gets confusing when dealing with dimensions and static arrays IMHO.

I agree. I have raised this topic time ago with no results so far. I find it surprising that Walter & Andrei too don't think of this as confusing :-|

Bye,
bearophile
July 05, 2011
On 7/5/2011 2:00 AM, Jonathan M Davis wrote:
> On 2011-07-04 23:56, Jonathan M Davis wrote:
>> On 2011-07-04 23:42, Bellum wrote:
>>> Can anyone point me in the right direction for doing something like this
>>>
>>> in D:
>>>       char[][] anArray;
>>>       int rows, cols;
>>>
>>>       ...
>>>
>>>       anArray = new char[rows][cols];
>>>
>>> It isn't possible in this way because "rows cannot be read at compile
>>> time", which seems to me to be the point of dynamic arrays. :P
>>
>> auto anArray = new char[][](rows, cols);
>>
>> Putting the numbers directly in the brackets tries to create a static array
>> once you get beyond the first dimension. So,
>>
>> auto anArary = new char[4][5];
>>
>> would create a dynamic array of length for with elements which are static
>> arrays of length 5. If you want it to by dynamic all the way, you need to
>> put the dimensions in the parens like above. Personally, I _never_ put
>> them in the brackets, even when the dynamic array has just one dimension.
>> It's just simpler to always put them in the parens and not worry about it.
>
> Correction,
>
> auto anArray = new char[4][5];
>
> would create a dynamic array of length 5 of static arrays with length 4,
> though
>
> auto anArray = new char[][](4, 5);
>
> does create a dynamic array of length 4 of dynamic arrays of length 5. It
> quickly gets confusing when dealing with dimensions and static arrays IMHO.
>
> - Jonathan M Davis

Wow, that is confusing. I think I'll stick to using parans, too; thanks for the tip!
July 05, 2011
> If you want it to by dynamic all the way, you need to put
> the dimensions in the parens like above. Personally, I _never_ put them in the brackets, even when the dynamic array has just one dimension. It's just
> simpler to always put them in the parens and not worry about it.

Maybe we should force the parens approach even for one dimension.
At least dmd should give better diagnostics. It's damn hard to even find that syntax in the docs.
July 05, 2011
On 2011-07-05 11:29, Trass3r wrote:
> > If you want it to by dynamic all the way, you need to put
> > the dimensions in the parens like above. Personally, I _never_ put them
> > in the brackets, even when the dynamic array has just one dimension.
> > It's just
> > simpler to always put them in the parens and not worry about it.
> 
> Maybe we should force the parens approach even for one dimension.
> At least dmd should give better diagnostics. It's damn hard to even find
> that syntax in the docs.

The problem is that there's nothing wrong with putting the dimensions in the brackets. It makes perfect sense _if you want dynamic arrays of static arrays_. However, that's not normally what people want. _Everyone_ who attempts to create a multidimensional dynamic array runs into this problem.

Putting the dimension in the brackets for a single dimension dynamic array matches exactly what's going on when you put the dimensions in the brackets with multi-dimension arrays. So, disallowing it wouldn't really make sense.

The issue is that it having multi-dimensional arrays where elements are static arrays makes perfect sense under certain circumstances, and it uses pretty much exactly the syntax that you'd expect it to if you were looking for that, but that that syntax is exactly what people try to use when using multi- dimensional arrays which are purely dynamic. So, this screws over everyone, but changing it risks removing a valid feature.

So, I really don't know how it should be handled. I fear that it's like how

int[5][4] a;
int a[4][5];

produce the same array. It matches perfectly how the language works in general but is exactly the opposite of what programmers expect, since they don't think like a compiler. Changing it makes the language inconsistent, but keeping it as-is causes problems for everyone using the language. It sucks pretty much no matter what you do. Maybe someone can come up with a way to clean things up, but as it stands, static arrays tend to screw over programmers until they understand their quirks (generally after getting bitten by errors like the OP ran into).

The one thing that _is_ clear, however, is that if the online docs are not clear about the paren syntax, then they should be updated. And they should probably explain the issue of dynamic arrays of static arrays more clearly so that those who read the docs will at least have some clue what is going on and avoid this issue.

- Jonathan M Davis