15-Sep-2013 12:39, monarch_dodra пишет:
On Saturday, 14 September 2013 at 06:18:02 UTC, Jonathan M Davis wrote:
I have a few issues with ref counted.

First, if you *ever* place one in an array or an AA, then you will leak.
It is NOT designed for simply incorporating reference, but for
deterministic finalization.

Another problem with built-in AAs...


Second, it has an elaborate postblit and opAssign. This is not a big
issue in itself, but their sole existence does cause dmd to generate
code that is sub-optimal. It also means it can't take the "optimal"
route in a lot of algorithms (array has to emplace each element
individually, for example).

Seriously we could do a better job then that.. For instance blit the whole data, then call postblits on that range. Exception safety would be trickier to achieve. Even better one day I now expect compiler to be able to know that e.g. RefCounted is registered as ARC-capable type then the compiler should elide call to ref-counting.

Finally, a RefCounted will implicitly cast to its payload. I think this
is *horrible*. Before you know it, the Payload will have "jettisoned"
its wrapper, and you'll be operating on your value-type payload "raw".
For example:
void foo(T t);
RefCounted!T myRecCounted;
foo(myRefCounted); //Passes. Oops!

Well it does a copy. Which is IMO perfectly fine.
If you want to prevent that (at least in theory) you should simply mark postblit of T as disabled.


The workaround would be to either require explicit "get" to go from ref
counted to payload (breaking existing code), or to entirelly wrap the
RefCounted as a member inside the struct (requires boilerplate code).

There is no need to prevent that in general case. Only RAII kind of things implemented with RefCounted would have problem copying-out the payload but these should have post-blit disabled for their "value" and consequently would not compile.

--------

Overall, if I need a reference semantic struct, I find it much simpler
for it to just hold a GC pointer to a payload.

Ehm.. Isn't finalized class is just that? Plus bit of overhead for monitor.

Though to be honest, as H.S. Teoh, I seriously wonder why I even bother,
when I could just use a final class. With proper "private constructors +
non-member "make" function", you can make your choice outright
transparent to the final user too, meaning you can "fast prototype" with
classes, and later change to structs if you think it is worth it.

This is true. And in fact I would encourage every D programmer to never expose constructors and always provide factory functions. These days constructors are constrained by a set of arcane limitations thusly suck beyond measure in every way possible. But you need them to say initialize immutable members, hence _use_ - but don't _expose_ them.

--
Dmitry Olshansky

Reply via email to