www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange behavior of array

reply VlasovRoman <vlasovroman.ru yandex.ru> writes:
I get it in dmd 2.068.2 and dmd 2.069-b2. I think, that this 
behavior some strange:

I have some code:

enum int m = 10;
enum int n = 5;

ubyte[m][n] array;
for(int x = 0; x < m; x++) {
	for(int y = 0; y < n; y++) {
		array[x][y] = cast(ubyte)(x + y);
	}	
}

In runtime i get range violation error. Helps to change the index 
when accessing the array. What I don't understand?

Thanks.
Oct 15 2015
parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 16/10/15 3:39 PM, VlasovRoman wrote:
 enum int m = 10;
 enum int n = 5;

 ubyte[m][n] array;
 for(int x = 0; x < m; x++) {
      for(int y = 0; y < n; y++) {
          array[x][y] = cast(ubyte)(x + y);
      }
 }
First on the left(declaration), last on the right(index/assign). void main() { enum int m = 10; enum int n = 5; ubyte[m][n] array; for(int x = 0; x < m; x++) { for(int y = 0; y < n; y++) { array[y][x] = cast(ubyte)(x + y); } } }
Oct 15 2015
parent reply VlasovRoman <vlasovroman.ru yandex.ru> writes:
On Friday, 16 October 2015 at 02:46:03 UTC, Rikki Cattermole 
wrote:
 On 16/10/15 3:39 PM, VlasovRoman wrote:
 enum int m = 10;
 enum int n = 5;

 ubyte[m][n] array;
 for(int x = 0; x < m; x++) {
      for(int y = 0; y < n; y++) {
          array[x][y] = cast(ubyte)(x + y);
      }
 }
First on the left(declaration), last on the right(index/assign). void main() { enum int m = 10; enum int n = 5; ubyte[m][n] array; for(int x = 0; x < m; x++) { for(int y = 0; y < n; y++) { array[y][x] = cast(ubyte)(x + y); } } }
Oh, thank you. Some strange solution.
Oct 15 2015
parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 16 October 2015 at 03:01:12 UTC, VlasovRoman wrote:

 Oh, thank you. Some strange solution.
D doesn't have multidimensional built-in arrays, but rectangular arrays. Think of it this way: int[3] a1; a1 is a static array of 3 ints. Indexing it returns an int. We can think of it like this: (int)[3] On the same lines: int[3][4] a2; a2 is a static array of 4 static arrays of 3 ints. In other words: (int[3])[4]. Therefore, int[0] returns the first int[3], int[1] the second, and so on. int[0][1] returns the second element of the first int[3]. Rikki's solution to your problem was to reverse the indexes when reading the array. But if you want to index it just as you would in C or C++, you should reverse the indexes in the declaration. Where you declare int[rows][columns] in C, you would declare int[columns][rows] in D, then reading from them is identical.
Oct 15 2015
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, October 16, 2015 04:39:57 Mike Parker via Digitalmars-d-learn wrote:
 On Friday, 16 October 2015 at 03:01:12 UTC, VlasovRoman wrote:

 Oh, thank you. Some strange solution.
D doesn't have multidimensional built-in arrays, but rectangular arrays. Think of it this way: int[3] a1; a1 is a static array of 3 ints. Indexing it returns an int. We can think of it like this: (int)[3] On the same lines: int[3][4] a2; a2 is a static array of 4 static arrays of 3 ints. In other words: (int[3])[4]. Therefore, int[0] returns the first int[3], int[1] the second, and so on. int[0][1] returns the second element of the first int[3]. Rikki's solution to your problem was to reverse the indexes when reading the array. But if you want to index it just as you would in C or C++, you should reverse the indexes in the declaration. Where you declare int[rows][columns] in C, you would declare int[columns][rows] in D, then reading from them is identical.
That does work currently, but there's talk off and on about deprecating the C syntax, so that may happen at some point, just like the C function pointer syntax was deprecated. Regardless, using the C array declaration syntax is generally discouraged - though the fact that the D syntax for static arrays is basically the reverse of what folks expect (much as it makes perfect sense from the compiler's point of view with how types are put together) definitely does make things confusing. - Jonathan M Davis
Oct 16 2015
parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 16 October 2015 at 07:25:16 UTC, Jonathan M Davis 
wrote:

 That does work currently, but there's talk off and on about 
 deprecating the C syntax, so that may happen at some point, 
 just like the C function pointer syntax was deprecated. 
 Regardless, using the C array declaration syntax is generally 
 discouraged - though the fact that the D syntax for static 
 arrays is basically the reverse of what folks expect (much as 
 it makes perfect sense from the compiler's point of view with 
 how types are put together) definitely does make things 
 confusing.
I'm not talking about using C array declaration syntax in D. I'm just saying that the indexes in the declaration should be reversed. Perhaps I should be more explicit. int foo[rows][columns]; // In C int[columns][rows] foo; // In D
Oct 16 2015
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, October 16, 2015 08:37:09 Mike Parker via Digitalmars-d-learn wrote:
 On Friday, 16 October 2015 at 07:25:16 UTC, Jonathan M Davis
 wrote:

 That does work currently, but there's talk off and on about
 deprecating the C syntax, so that may happen at some point,
 just like the C function pointer syntax was deprecated.
 Regardless, using the C array declaration syntax is generally
 discouraged - though the fact that the D syntax for static
 arrays is basically the reverse of what folks expect (much as
 it makes perfect sense from the compiler's point of view with
 how types are put together) definitely does make things
 confusing.
I'm not talking about using C array declaration syntax in D. I'm just saying that the indexes in the declaration should be reversed. Perhaps I should be more explicit. int foo[rows][columns]; // In C int[columns][rows] foo; // In D
Oh that. Yeah. In terms of the dimensions, int[c][b][a] foo; is equivalent to auto foo = new int[][][](a, b, c); though obviously the actual types are different. So, if you use static arrays, you pretty much have to flip the order of the dimensions and think of them going from right-to-left in the declaration, whereas everywhere else (including indexing the static array), they go from left-to-right. It makes perfect sense given how the compiler reads types, but I'm honestly inclined to think that it was a mistake, particularly since we already broke the read outward from the variable name rule from C when we made it so that const had to go on the left rather than the right and made it use parens. Regardless, we're stuck with it at this point. And we'll just have to keep explaining to folks why static arrays aren't working as they expected... - Jonathan M Davis
Oct 16 2015