Implementing SmartPtr - compiler bug?

Szymon Gatner via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Oct 27 02:11:33 PDT 2014


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.


More information about the Digitalmars-d-learn mailing list