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: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@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: -------