I modified Walter's sample code to this: http://dpaste.dzfl.pl/f3d854feede9. It uses malloc for both the array and the reference count, and also uses @trusted minimally. I inserted assert()s here and there to clarify the workings. Nothing big except for the careful use of @trusted.

I'll use this as a basis of some exegesis.

1. The code is a bit more complicated than it should. Overall this is not a biggie; regular D users are not supposed to write reference counted slices casually. But I was bummed that e.g. I found no way to call emplace() @safe-ly.

2. Michel's point (https://issues.dlang.org/show_bug.cgi?id=14221) reveals the largest issue with RC/GC integration. We need to find a fix for it if we want to have the GC lift cycles.

3. opIndex ("here's the magic") is the most interesting part of the proposal. It disallows unsafe use such as:

@safe ref int fun()
{
   auto a = RCArray!int([1, 2, 3]);
   return a[1];
}

Nice. I'd go as far as saying that barring implementation bugs, with DIP25 in tow, and after we fix 14221, it's impossible to get an invalid memory access with RCArray in @safe code. This (we offer a way to design @safe arrays and more generally structs that are @safe) is interesting and important.

That said there is a rub. The part that deallocates memory in the destructor must be @trusted. That is fine, but the trustworthiness of that code depends on the "return" attribute in opIndex. Furthermore, if the author of RCSlice forgets to put "return" there, the compiler won't help - it just allows wrong code like fun() above to compile and run (causing dangling pointer use).

So: does DIP25 allow safe slices? Looks that way, though a proof would be nice. Does it allow other safe interesting structs that own data? Very likely. Does it allow really sophisticated ownership schemes? We need to explore that. Does it protect against bugs in implementations of safe ownership schemes that explicitly release memory? Not too well. I think the prevalent idiom will be to accompany such artifacts with unittests that make sure unsafe uses (such as fun() above) do not compile.


Andrei

Reply via email to