As far as I understand, this is generally how ref counting is supposed to be done, and with a simple payload like `int` it's supposed to be properly safe already:
----
module my_rc_thingy;
struct RCint
{
import core.stdc.stdlib: free, malloc;
private static struct Store
{
int payload;
uint count;
}
private Store* s = null;
int value() @safe { return s.payload; }
this(int value) @trusted
{
s = cast(Store*) malloc(Store.sizeof);
*s = Store(value, 1);
}
this(this) @safe { ++s.count; }
~this() @trusted
{
if (--s.count == 0)
{
free(s);
s = null;
}
}
}
----
(There could be more checks for null, but dereferencing null crashes the program in an `@safe` manner anyway, so why bother in an example.)
I don't have to worry about DIP 1000, because I don't give out references to the payload or to the reference count. Right?
But what about `tupleof`? It ignores `private` and it's allowed in `@safe` code:
----
void main() @safe
{
import my_rc_thingy: RCint;
import std.stdio;
int* p;
{
auto rc = RCint(42);
p = &rc.tupleof[0].payload; /* uh-oh */
}
writeln(*p); /* garbage */
auto rc = RCint(42);
{
auto rc2 = rc; /* increasing the refcount */
rc2.tupleof[0].count = 1; /* uh-oh */
}
writeln(rc.value); /* garbage */
}
----
So am I missing something or should `tupleof` not be allowed to ignore `private` in `@safe` code?
|