On Monday, 27 October 2014 at 07:31:34 UTC, Shachar Shemesh wrote:
For reasons I won't go into (but should be fairly obvious), I
am trying to write code that does not rely on the garbage
collector. As such, I'm using reference counting structs
allocated on a pool.
To keep things sane, I'm trying to use RAII semantics, and to
that end, a smart pointer that calls "incref" and "decref" when
appropriate.
The SmartPtr struct implements this(T*), this(SmartPtr),
this(this), ~this(), opAssign(SmartPtr), opAssign(ref SmartPtr)
and opAssign(T*). To the best of my understanding this should
be enough to catch all relevant cases.
All works fine except one case:
Foo foo;
SmartPtr!Foo[4] array;
array[0] = foo;
assert(foo.refcount == 1);
array = array.init;
assert(foo.refcount == 0, "This assert fails");
I am compiling this on dmd v2.065
Switching the init line to "array[] = SmartPtr!Foo.init" makes
the second assert pass.
To the best of my understanding, "array = array.init" should
always be equivalent to "array[] = typeof(array[0]).init" for
static arrays. Am I missing something? Is this a compiler bug?
Thanks,
Shachar
You have created dynamic array of SmartPtrs. In that case they
now live on GS's heap and destructor calls are no longer
deterministic (and in fact are not guaranteed at all). That is
the very first things that gets C++ programmers coming to D
(happened to me too). RAII does not work in D. At least not how
C++ would expect it to.