digitalmars.D.bugs - [Issue 11637] New: Statically disallow sparse array literals and associative array literals with duplicate indexes
- d-bugmail puremagic.com (89/89) Nov 28 2013 https://d.puremagic.com/issues/show_bug.cgi?id=11637
https://d.puremagic.com/issues/show_bug.cgi?id=11637 Summary: Statically disallow sparse array literals and associative array literals with duplicate indexes Product: D Version: D2 Platform: x86 OS/Version: Windows Status: NEW Keywords: accepts-invalid Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: bearophile_hugs eml.cc This bug report is borderline with being an enhancement request. DMD 2.065alpha accepts code like this, where duplicated keys in both dynamic array literals and in associative array literals defined with the sparse syntax: void main() { int[] a = [0:10, 0:20]; int[int] aa = [0:10, 0:20]; } I don't want to use this language "feature", and on the other hand I have had some mistakes like this in my D code not caught statically by the compiler. So I propose for D to statically disallow duplicated keys in both those cases, and give two compilation errors. I think that's just a possible source of bugs with no enough usefulness. -------------- Note that here I am not asking about disallowing inserting multiple times a key-pair in an associative array, this is normal and useful: void main() { int[int] aa; aa[0] = 10; aa[0] = 20; } -------------- The compiler didn't catch a bug of mine in a large dynamic array literal defined with the sparse syntax, I have assumed it was safer to specify enum keys like this, but currently this compiles with no errors: import std.traits, std.range, std.algorithm; enum Foo : size_t { f1, f2, f3 } enum Bar : size_t { b1, b2 } // Assert that both enums are usable as array indexes. static assert(__traits(compiles, { size_t x = Foo.init; })); static assert([EnumMembers!Foo].equal(EnumMembers!Foo.length.iota)); static assert(__traits(compiles, { size_t x = Bar.init; })); static assert([EnumMembers!Bar].equal(EnumMembers!Bar.length.iota)); void main() { with (Foo) with (Bar) int[EnumMembers!Foo.length][EnumMembers!Bar.length] A = [b1: [f1:1, b1:2, f3:3], b2: [f1:4, f2:5, f3:4]]; } Note in that code there is one "b1" index that logically is of the wrong _type_ because it should be a Foo.f2 instead of Bar.b1. But currently there is no way in D to strongly specify the type of the indexes of an array (as in Ada language). In D you can only specify the type of the keys of associative arrays, and here indeed D catches that type mismatch bug: import std.traits: EnumMembers; enum Foo : size_t { f1, f2, f3 } enum Bar : size_t { b1, b2 } void main() { with (Foo) with (Bar) { int[Foo][Bar] AA; AA = [b1: [f1:1, b1:2, f3:3], b2: [f1:4, f2:5, f3:4]]; } } temp.d(7): Error: cannot implicitly convert expression (cast(Bar)0) of type Bar to Foo But associative arrays are slow at run-time compared to a regular fixed-size 2D array, so I have has to use the sparse syntax to define a fixed-size 2D array. Note that: assert(cast(size_t)Bar.b1 == cast(size_t)Foo.f1); So the value of the index in the fixed-size 2D array "A" defined using the sparse syntax is duplicated, yet D has not found my mistake. To help me avoid such mistakes I propose to statically (at compile-time) disallow array literals with duplicate keys. From the answers in the D newsgroup people seem to accept the idea: http://forum.dlang.org/thread/befwnwpitihpcjfbdarl forum.dlang.org (I'd also like in D arrays with strongly typed indexes (not associative arrays, just arrays) as in Ada, but that's an enhancement request left for other places. One of the many advantages of having strongly typed indexes is that with them sometime there is no need to verify array bounds even in non-release mode.) -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 28 2013