digitalmars.D - foreach limitations?
- Russ Lewis (16/16) Aug 12 2004 I ran into some unexpected complexities with foreach-ing over a
- Jan Bendtsen (17/29) Aug 12 2004 [snip]
- Russ Lewis (9/23) Aug 12 2004 They are both O(i*j) algorithms, so I would generally say that either
- Ilya Minkov (15/42) Aug 12 2004 I think what we need are real multidimensional arrays in 2.0 - what we
- Matthew (1/1) Aug 12 2004 One should be able to foreach over all the elements in a static array, o...
- Mikola Lysenko (18/25) Aug 12 2004 The reason is that dynamic arrays have two attributes
- Russ Lewis (11/38) Aug 12 2004 Sure, I know this. But you can assign a static array to a dynamic
I ran into some unexpected complexities with foreach-ing over a multidimensional static array. I tried this code, which didn't work: int[10][100] foo; foreach(inout int i; foo) { ... } I guess I can understand that you can't foreach over a multidimensional array. But it would be cool for 2.0. So I tried this next, which didn't work, either: int[10][100] foo; foreach(inout int[] a; foo) foreach(inout int i; a) { ... } It seems that if you foreach over something, and the elements are static arrays, you can't have a dynamic array as the foreach variable. So I was left with this ugly code: int[10][100] foo; foreach(inout int[10] a; foo) foreach(inout int i; a) { ... } So I'm wondering why we can't do my second example above. Is there some intentional reason why? Or just an oversight in the compiler?
Aug 12 2004
Hi, Russ Lewis wrote:I ran into some unexpected complexities with foreach-ing over a multidimensional static array. I tried this code, which didn't work: int[10][100] foo; foreach(inout int i; foo) { ... } I guess I can understand that you can't foreach over a multidimensional array. But it would be cool for 2.0. So I tried this next, which didn't work, either: int[10][100] foo; foreach(inout int[] a; foo) foreach(inout int i; a) { ... }[snip] On a tangentially related note, what is more efficient in terms of execution speed, the code above or int[10][100] foo; for(int i = 0; i < foo.length; i++) { for(int j = 0; j < foo[i].length; j++) { // Do some stuff, e.g., foo[i][j] = cosh(i*j); } } ? (ignoring any implications inout might have, if that makes a difference) I'm asking out of curiosity... what is the 'best' practice in a case like this? Cheers, Jan
Aug 12 2004
Jan Bendtsen wrote:On a tangentially related note, what is more efficient in terms of execution speed, the code above or int[10][100] foo; for(int i = 0; i < foo.length; i++) { for(int j = 0; j < foo[i].length; j++) { // Do some stuff, e.g., foo[i][j] = cosh(i*j); } } ? (ignoring any implications inout might have, if that makes a difference) I'm asking out of curiosity... what is the 'best' practice in a case like this?They are both O(i*j) algorithms, so I would generally say that either one is as good as the other. The two loops are really the same thing, so the real difference is going to be how good the compiler is at optimizing the loop. You don't really know how good your compiler will be until you look at the assembly language. So I would recommend that you use whatever loop you think is more readable and maintainable (I prefer foreach, though you may think differently).
Aug 12 2004
Jan Bendtsen schrieb:I think what we need are real multidimensional arrays in 2.0 - what we have now is arrayarrays. I have suggested them multiple times, and Norbert Nemec has formulated a detailed proposal in "Proposal for multidimensional arrays". They would solve this problem neatly as well. I think also that a template library would close the for-each-element gap.I ran into some unexpected complexities with foreach-ing over a multidimensional static array. I tried this code, which didn't work: int[10][100] foo; foreach(inout int i; foo) { ... } I guess I can understand that you can't foreach over a multidimensional array. But it would be cool for 2.0.This looks like a bug. int[10] ought to be assignable to int[], though apparently not all parts of the compiler are aware of that. :) Although this might be a spot where it's better not to convert due to performance reasons.So I tried this next, which didn't work, either: int[10][100] foo; foreach(inout int[] a; foo) foreach(inout int i; a) { ... }On a tangentially related note, what is more efficient in terms of execution speed, the code above or int[10][100] foo; for(int i = 0; i < foo.length; i++) { for(int j = 0; j < foo[i].length; j++) { // Do some stuff, e.g., foo[i][j] = cosh(i*j); } } ? (ignoring any implications inout might have, if that makes a difference) I'm asking out of curiosity... what is the 'best' practice in a case like this?I think it doesn't make any difference right now, but foreach offers much more optimization potential in the primitive cases. Besides, it's the only sane way to iterate through other containers, such as associative arrays and user-defined types, so i'd say foreach is preferred. -eye
Aug 12 2004
One should be able to foreach over all the elements in a static array, or any slice thereof.
Aug 12 2004
In article <cfgd71$2flp$1 digitaldaemon.com>, Russ Lewis says...It seems that if you foreach over something, and the elements are static arrays, you can't have a dynamic array as the foreach variable. So I was left with this ugly code: int[10][100] foo; foreach(inout int[10] a; foo) foreach(inout int i; a) { ... } So I'm wondering why we can't do my second example above. Is there some intentional reason why? Or just an oversight in the compiler?The reason is that dynamic arrays have two attributes 1). Length of the array 2). A pointer to the start of the array Static arrays on the other hand directly reference a chunk of memory allocated for the array elements. The compiler treats both types differently. Your original code would work if you declared foo as such A foreach over a static array and a foreach over a dynamic array are two slightly different things. The static-foreach looks up the name in the symbol table and finds the length of the array once at compile time, while the dynamic-foreach simply uses the length attribute. You can see evidence of this in the .sizeof method for the two different array types. In this example, a.sizeof = 20 while b.sizeof = 8 (32 bits for start of array, 32 bits for length)
Aug 12 2004
Mikola Lysenko wrote:In article <cfgd71$2flp$1 digitaldaemon.com>, Russ Lewis says...Sure, I know this. But you can assign a static array to a dynamic array. But why can't the compiler turn this code: int[10][100] foo; foreach(inout int[] a; foo) foreach(inout int i; a) { ... } into this code: int[10][100] foo; foreach(inout int[10] _compiler_temp__a; foo) { int[] a = _compiler_temp__a; foreach(inout int i; a) { ... } }It seems that if you foreach over something, and the elements are static arrays, you can't have a dynamic array as the foreach variable. So I was left with this ugly code: int[10][100] foo; foreach(inout int[10] a; foo) foreach(inout int i; a) { ... } So I'm wondering why we can't do my second example above. Is there some intentional reason why? Or just an oversight in the compiler?The reason is that dynamic arrays have two attributes 1). Length of the array 2). A pointer to the start of the array Static arrays on the other hand directly reference a chunk of memory allocated for the array elements. The compiler treats both types differently. Your original code would work if you declared foo as such A foreach over a static array and a foreach over a dynamic array are two slightly different things. The static-foreach looks up the name in the symbol table and finds the length of the array once at compile time, while the dynamic-foreach simply uses the length attribute.
Aug 12 2004