Summary: AA has inconsistent and unreasonable requirements for
                    iterating over reference-type index
           Product: D
           Version: D2
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD

--- Comment #0 from Steven Schveighoffer <> 2010-07-01 
05:46:43 PDT ---
Given the following:
class C {}
struct S {int u;}

uint[C] aa1;
uint[S*] aa2;

We have many issues with foreach:

foreach(C k, v; aa1) {} // compiles
foreach(S *k, v; aa2) {} // does not compile, k must be const(S)*
foreach(ref C k, v; aa1) {} // compiles(!)
foreach(ref const(S) *k, v; aa2) {} // compiles

Here are the issues:

first, ref should *never* be allowed as an index for AAs.  I hope that someday
this can be extended to all user types (see related bug 2443).

Second, we have a strange restriction for pointer key types in that the key
must be designated tail-const.  I sort of understand this in that you don't
want the key to be changing after adding, but this restriction is impossible to
enforce -- one can easily change the original pointer passed in.  i.e.:

auto x = new S;
aa2[x] = 5;
x.u = 3; // oops!

In addition, the same restriction isn't required for classes, so you *can*
change the class data during iteration.  Finally, even though the pointer is
tail-const, allowing a reference to it means you can change the pointer itslef!

I think the const restriction should be removed, it's not enforceable and makes
generic code much more difficult, since it's inconsistent.  In addition, we can
amend the documentation for AAs to indicate that if you want sane AAs, you
should use immutable keys.  Otherwise, it's on you never to change the keys
after adding them.

Also, as mentioned, ref indexes should not be allowed.  This used to be the
case, not sure why it was changed.

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to