ref is unsafe

Jonathan M Davis jmdavisProg at gmx.com
Sun Dec 30 00:37:32 PST 2012


After some recent discussions relating to auto ref and const ref, I have come 
to the conlusion that as it stands, ref is not @safe. It's @system. And I 
think that we need to take a serious look at it to see what we can do to make 
it @safe. The problem is combining code that takes ref parameters with code 
that returns by ref. Take this code for example:

ref int foo(ref int i)
{
    return i;
}

ref int bar()
{
    int i = 7;
    return foo(i);
}

ref int baz(int i)
{
    return foo(i);
}

void main()
{
    auto a = bar();
    auto b = baz(5);
}

Both bar and baz return a ref to a local variable which no longer exists. They 
refer to garbage. It's exactly the same problem as in

int* foo(int* i)
{
    return i;
}

int* bar()
{
    int i = 7;
    return foo(&i);
}

void main()
{
    auto a = bar();
}

However, that code is considered @system, because it's taking the address of a 
local variable, whereas the code using ref is considered to be @safe. But it's 
just as unsafe as taking the address of the local variable is. Really, it's 
the same thing but with differing syntax.

The question is what to do about this. The most straightforward thing is to 
just make ref parameters @system, but that would be horrible. With that sort 
of restriction, a _lot_ of code suddenly won't be able to be @safe, and it 
affects const ref and auto ref and anything else along those lines, so whatever 
solution we come up with for having auto ref with non-templated functions will 
almost certainly have the problem, and once that works, I'd expect it to be 
used pretty much by default, making most D code @system, which would be a 
_big_ problem.

Another possibility is to make ref imply scope, but given the transitive 
nature of that, that could be _really_ annoying. Maybe it's the correct 
solution though.

Another possibility would be to make it so that functions with a ref parameter 
are only @system if they also return by ref (the lack of ability to have ref 
variables outside of parameters and return types saves us from such a ref 
being squirreled away somewhere). I don't know how good or bad an idea that 
is. It certainly reduces how much code using ref would have to be @system, but 
it might not be sufficient given how much stuff like std.algorithm uses auto ref 
for its return types.

And maybe another solution which I can't think of at the moment would be 
better. But my point is that we currently have a _major_ hole in SafeD thanks 
to the combination of ref parameters and ref return types, and we need to find 
a solution.

- Jonathan M Davis


Related: http://d.puremagic.com/issues/show_bug.cgi?id=8838


More information about the Digitalmars-d mailing list