Newbie initial comments on D language - scope

Janice Caron caron800 at googlemail.com
Sun Feb 3 06:16:53 PST 2008


On 03/02/2008, Edward Diener <eddielee_no_spam_here at tropicsoft.com> wrote:
> But again that does not change the type of 'char'.

I hope you're not implying that I said it did.

> In arguing for 'scope' at the type level, as in 'scope class C { ... }'
> I was arguing that 'scope' applies some attribute to the type of C. The
> class designer is making a conscious decision in designing his type in
> order to tell the compiler that all objects of his type need
> deterministic destruction in a system which normally implements
> non-deterministic destruction via GC. That says something about the type
> per se.

Having actually implemented reference counting in C++, I know how it
works. For any type T (doesn't matter if it's a class, a struct, or
just an int), you make two additional types. The first of these just
adds a reference counter:

    class Countable(T)
    {
        uint refCount;
        T val;
    }

and the second is what is exposed to the end user

    struct RefCounted(T)
    {
        Countable!(T) val;
        /* and appropriate ref-counting functions */
        /* and appropriate forwarding functions */
    }

It should be clear that there is no way to cast a RefCounted!(T) to a
T. If you want the following to compile:

    RefCounted!(C) c = whatever;
    C d;
    d = c;

Then the only way to do that would be to have RefCounted!(C) be
implicitly castable to C, presumably by having opImplicitCast() return
c.val.val. This would be disasterous. The moment you allow that,
suddenly you have uncounted references running around. It would then
be possible to do the following:

    C d;
    {
        RefCounted!(C) c = new RefCounted!(C)();
        d = c;
    }
    /* Whoops! d now points to a destructed object! */

Instead, what you'd /really/ want the class designer to do is
something like this:

    struct PrivateFileHandle
    {
        private this(string filename) { /*...*/ }
        ~this() { /*...*/ }
        /* other functions as appropriate */
    }
    alias RefCounted!(PrivateFileHandle) FileHandle;

That way, the caller only has to declare

    FileHandle fh;

but gets it ref-counted. (And there is no way for it not to be refcounted).

If we go the way of "scope C" meaning "RefCounted!(C)" under the hood,
then whether or not you'll need the word "scope" depends on whether
you want to refer to the refcounted type or the underlying type.



More information about the Digitalmars-d mailing list