On 10/15/2010 05:55 AM, Walter Bright wrote:


D has pointers that you cannot do arithmetic on - called references. The
semantics are carefully designed so a function cannot return a reference
to a local, this is so that such locals will not have to be put onto the
garbage collected heap. Hence, references are usable in safe mode.

I think the above statement needs clarification. Honestly, I don't understand how references to non-class objects are supposed to work in SafeD. Consider:

struct S
{
    int x;
}

static S s;
ref S foo()
{
    return s;
}

void bar()
{
    foo().x = 1;
    assert(s.x == 1); // ok, s updated

    auto s2 = foo();
    s2.x = 2;
    assert(s.x == 2); // not ok, we need to use a pointer as below

    auto s3 = &foo();
    s3.x = 3;
    assert(s.x == 3); // ok, s updated
}

Since pointers are not allowed in SafeD, any non-trivial operations on a referenced object are extremely awkward because you have to pile all of them around the call returning the reference. For example, if I want to update s and then pass it by reference to another function:

void baz(ref S s)
{
}

void bar()
{
    baz(foo(s).x = 1); // awkward
}

Of course, we can use tricks like a @trusted Ref struct wrapping a pointer to the referenced object. But I don't know how such a struct can prevent one from returning locals:

struct Ref(T)
{
    T* p;
    this(ref T v) { p = &v; }
    ref T getRef() { return *p; }
    alias getRef this;
}

ref Ref!T byref(T)(ref T v)
{
    return Ref!T(v);
}

ref S foo()
{
    S s;
    return byref(s); // local successfully escaped
}

Please comment.


Reply via email to