May 06, 2004
Hi there,

trying to write up my proposal for multidimensional array references, I stumbled over a peculiar strangeness in the current syntax of arrays.

        const int A = 2;
        const int B = 3;
        alias mytype[A][B] M1;
        alias mytype[A] Mtmp;
        alias Mtmp[B] M2;

As I understand it, M1 and M2 should be identical, since [N] is just a type modifier for anything that stands in front of it. Now, lets use it.

        M2 m2;
        for(int b=0;b<B;b++) {
                Mtmp mt = m2[b]; // dereferencing the outer array
                for(int a=0;a<A;a++) {
                        mytype m = mt[a]; // now the inner array
                        assert(m == (m2[b])[a]); // just a parenthesis for clarity
                        assert(m == m2[b][a]);   // identical to previous line
                }
        }

So obviously, an array declared as mytype[A][B] has to be used as m1[b][a] !

Tracing this strangeness back, it actually comes from the change from C-style array declarations to D-style array types. Going back to C syntax step by step, we get three equivalent declaration statements:

        mytype[A][B] m;
is equivalent to
        mytype[A] m[B];
is equivalent to
        mytype m[B][A];

The situation might become clearer when considering something like:

        mytype[char[]][3] X;
        X[2]["s"] = something;

I do not see a simple solution out of this. The core problem is somewhere in the strangeness of prefix and postfix operators. If the typemodifier uses postfix notation, so the indexing operators unravelling the type have to be applied in reverse order. One clean but ugly solution would be to make type modifiers prefix operators "[B][A]int m;". But then, the "*" modifier would still have to stay postfix, since the corresponding dereferencing operator "*" is a prefix operator, leaving us with the old problem of precedence levels.

Alternatively, we can just accept the situation, document it clearly, and encourage people to use rectangular array notation once we have it:

        mytype[B,A] m;
would be equivalent to
        mytype[A][B] m;

yielding truely C-aligned arrays with B rows and A columns, each row saved in a continuous block.

Ciao,
Nobbi