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?

Reply via email to