[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