Bug 3383 – newVoid

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2009-10-09T10:08:00Z
Last change time
2015-06-09T01:29:41Z
Keywords
patch, performance
Assigned to
dsimcha
Creator
dsimcha

Comments

Comment #0 by dsimcha — 2009-10-09T10:08:58Z
D's new keyword for allocating dynamic arrays initializes the data to T.init. This is a perfectly reasonable safe default. However, there should be an obvious way to optimize this out if one is sure one doesn't need it, as there is for static arrays. Below is a proposed function, newVoid(), that should go in std.array to allow such a thing. import core.memory; /**Gives the block attribute that a block containing type T should have, * i.e. scan or NO_SCAN.*/ GC.BlkAttr blockAttribute(T)() { if(typeid(T).flags & 1) { return cast(GC.BlkAttr) 0; } else { return GC.BlkAttr.NO_SCAN; } } unittest { assert(blockAttribute!(uint)() == GC.BlkAttr.NO_SCAN); assert(blockAttribute!(void*)() == cast(GC.BlkAttr) 0); } /**Returns a new array of type T w/o initializing elements. * * Examples: * --- * auto foo = newVoid!uint(5); * foreach(i; 0..5) { * foo[i] = i; * } * --- */ T[] newVoid(T)(size_t length) { T* ptr = cast(T*) GC.malloc(length * T.sizeof, blockAttribute!(T)()); return ptr[0..length]; } unittest { // Mostly just see if this instantiates. auto foo = newVoid!uint(5); foreach(i; 0..5) { foo[i] = i; } foreach(i; 0..5) { assert(foo[i] == i); } }
Comment #1 by andrei — 2011-06-05T08:18:18Z
Reassigning this to David. David, this is a sensible primitive. You may want to make it into a pull request, probably in std.array or even in druntime. A few notes: 1. newVoid is not very indicative, I'd suggest something long and obvious-looking (as this can be an unsafe function), e.g. makeUninitializedArray!int(100). 2. Since 0 seems to be an actually used constant of GC.BlkAttr, you may as well give it a name, e.g. NONE. Thanks!
Comment #2 by bearophile_hugs — 2011-06-05T12:29:45Z
Nicer and cleaner: // doesn't initialize foo1 auto foo1 = new uint[5] = void; // initializes the dynamic array to 5, avoiding a double initialization auto foo2 = new uint[5] = 5; That syntax is inspired by static array syntax: uint[5] a1 = void; uint[5] a2 = 5;
Comment #3 by bearophile_hugs — 2011-06-06T03:26:11Z
One case worth considering: auto mat = new int[5][5]; foreach (row; mat) row[] = 10; The way used to initialize a matrix to void is useful to initialize all of it to a defined value too.
Comment #4 by dsimcha — 2011-08-12T20:43:48Z
This evolved into std.array.uninitializedArray.