[Issue 5603] New: Initialization syntax for dynamic arrays

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Feb 16 16:25:37 PST 2011


http://d.puremagic.com/issues/show_bug.cgi?id=5603

           Summary: Initialization syntax for dynamic arrays
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody at puremagic.com
        ReportedBy: bearophile_hugs at eml.cc


--- Comment #0 from bearophile_hugs at eml.cc 2011-02-16 16:23:03 PST ---
Fixed-sized arrays allow to specify an initialization value, or to not specify
one, or to leave the stack memory untouched, for special situations where
performance matters a lot:

// program #1
void main() {
    int[5] a2 = void;

    int[5] a1 = 1;

    int[5][5] m2 = void;

    int[5][5] m1 = 1;
}


Dynamic arrays don't allow to specify an initialization value (expecially after
the deprecation of 'typedef', that used to allow the definition of a new int
type with a different init value). DMD has no syntax to allocate an unitialized
array, and currently it is not able to avoid double initializations of dynamic
arrays, an example:


// program #2
void main() {
    auto a1 = new int[5];
    a1[] = 1;
}


Asm of program #2 (optimized built). __d_newarrayT performs a first
initialization to zero, __memset32 performs a second initialization:

__Dmain comdat
L0:     sub ESP,01Ch
        mov EAX,offset FLAT:_D11TypeInfo_Ai6__initZ
        push 5
        push EAX
        call near ptr __d_newarrayT
        mov 0Ch[ESP],EAX
        mov 010h[ESP],EDX
        push dword ptr 0Ch[ESP]
        push 1
        push EDX
        call near ptr __memset32
        add ESP,014h
        add ESP,01Ch
        xor EAX,EAX
        ret


So to translate the program #1 for dynamic arrays you need something like this
(I am not sure this is fully correct. GC.disable are used because m1/m2 contain
uninitialized pointers):


// program #3
import core.memory: GC;

void main() {
    uint ba1 = GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE;
    int n1 = 5;
    int[] a1 = (cast(int*)GC.malloc(int.sizeof * n1, ba1))[0 .. n1];

    uint ba2 = GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE;
    int n2 = 5;
    int[] a2 = (cast(int*)GC.malloc(int.sizeof * n2, ba2))[0 .. n2];
    a2[] = 1;

    uint ba3a = GC.BlkAttr.APPENDABLE;
    uint ba3b = GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE;
    int n3 = 5;
    GC.disable();
    int[][] m1 = (cast(int[]*)GC.malloc((int[]).sizeof * n3, ba3a))[0 .. n3];
    foreach (ref row; m1)
        row = (cast(int*)GC.malloc(int.sizeof * n3, ba3b))[0 .. n3];
    GC.enable();

    uint ba4a = GC.BlkAttr.APPENDABLE;
    uint ba4b = GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE;
    int n4 = 5;
    GC.disable();
    int[][] m2 = (cast(int[]*)GC.malloc((int[]).sizeof * n4, ba4a))[0 .. n4];
    foreach (ref row; m2) {
        row = (cast(int*)GC.malloc(int.sizeof * n4, ba4b))[0 .. n4];
        row[] = 1;
    }
    GC.enable();
}


So to avoid all that bug-prone mess I suggest to allow the fixed-sized array
syntax for dynamic arrays too:

// program #4
void main() {
    auto a2 = new int[5] = void;

    auto a1 = new int[5] = 1;

    auto m2 = new int[][](5, 5) = void;

    auto m1 = new int[][](5, 5) = 1;
}



An usage of unitialized memory:
http://research.swtch.com/2008/03/using-uninitialized-memory-for-fun-and.html

"An Efficient Representation for Sparse Sets" (1993), by Preston Briggs, Linda
Torczon:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.30.7319

>From programming pearls book:
http://books.google.it/books?id=kse_7qbWbjsC&pg=PA207&lpg=PA207&dq=programming+pearls+uninitialized&source=bl&ots=DfAXDLwT5z&sig=X53xYgD0wdn_Rwl7tFNeCiRt4No&hl=en&ei=HWVcTa35EYOdOsLI5OYL&sa=X&oi=book_result&ct=result&resnum=1&ved=0CBUQ6AEwAA

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


More information about the Digitalmars-d-bugs mailing list