On Friday, 6 March 2015 at 14:59:46 UTC, monarch_dodra wrote:
struct RCArray(E) {
 E[] array;
 int* count;
 ...
}
auto x =  RCArray([E()]);
E* t = &x[0];

But taking that address is unsafe to begin with. Do arguably, this isn't that big of a problem.

Taking the address is only really unsafe (in a non-RC'd type) if you don't have a lifetime tracking system. As long as the lifetime of the address taker is shorter than the address of the takee, it's not inherently unsafe. Whether D will end up with such a system is a different question.

But I still think there's value in having a separate RCData type, because you can save one pointer per instance of RCArray. Right now, if you take a slice of an RCArray, your working array might not start at the same place as the reserved memory array. Therefore you need to keep a pointer to the reserved memory in addition to your active working array. If the counter and the pointer to the original memory are in the same place, one pointer will get you both.

I think the idea is worth exploring.

Your first dual reference issue seems much more problematic, as there are always cases the compiler can't catch.

How so? If all we're talking about is RC'd types, the compiler can catch everything. I think the greater concern is that the workarounds will take a toll in runtime performance. I'll try to illustrate:

void fun(ref RCStruct a, ref RCStruct b);

auto x = new RCStruct;
fun(x, x);

This wouldn't be safe. If fun() contained a line "a = new RCStruct;", b will point to deleted memory for the rest of the function. The normal way to protect this to make sure there's another reference:

auto y = x;
fun(x,x);

This is actually safe, because y bumps the reference counter to 2 when initialized, which is enough to cover all possible reassignments of x. The compiler could do this automatically. It could detect that the parameter x aliases itself and create a temporary copy of x. But it would mean the runtime performance cost of the copy and postblit and destructor call. So D probably can't invest in that strategy, since the programmer should have a choice about it.

So it's not about it being impossible to deal with the safety problems here, just that the runtime cost is too high.

But there are some ways out. If the given type has no postblit, for example (or "opAddRef" for classes), there's no reason to mark the operation unsafe, since you know it's not reference counted. Also, const parameters are safe and won't be affected.

Reply via email to