www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11637] New: Statically disallow sparse array literals and associative array literals with duplicate indexes


           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

--- Comment #0 from bearophile_hugs eml.cc 2013-11-28 14:51:33 PST ---
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

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

Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 28 2013