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.

Reply via email to