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