www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Array alignment - fundamental problem/strangeness

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
                        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

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.

May 06 2004