There is a handy warning in DMD of the sort "escaping reference to a local variable". Below is a similar case which is wrong code but does not generate a similar warning.
We declare a function returning a reference to a slice. Inside, we return a reference to a newly-created slice of some array. This is an error but goes undetected by the compiler.
Example 1 (fixed length array):
-----
import std.stdio;
int [1] a;
ref int [] f ()
{
return a [0..1];
}
void main ()
{
auto s = f ();
writeln (s);
}
-----
Example 2 (variable length array):
-----
import std.stdio;
int [] a;
ref int [] f ()
{
return a [0..1];
}
void main ()
{
a = new int [1];
auto s = f ();
writeln (s);
auto t = f ();
writeln (t);
}
-----
With DMD 2.062, the first example locally crashes with Access Violation after printing ~10 Mb of some garbage array slice. The second example prints an empty slice (instead of [0]) for s and then crashes for t.
Now, while returning "ref int []" instead of "int []" might have its uses, in my case it was a newbie mistake. I just wanted to return a slice of lvalues and didn't understand that the elements of the "int []" will be assignable for free. Thought I need an extra "ref" for that.
The case seems obvious: the function returns by reference an entity which was created on the stack just a few instructions before that.
Comment #1 by gassa — 2013-03-05T12:05:11Z
Interestingly, a local array and a delegate do generate a warning. However, the warning says "escaping reference to local variable a" which is not true: the problem lies in escaping reference to a local unnamed slice, not variable "a" which is legally visible to the caller. The non-ref versions compile and run without problems.
Example 3 (local fixed length array):
-----
import std.stdio;
void main ()
{
int [1] a;
ref int [] f ()
{
return a [0..1];
}
auto s = f ();
writeln (s);
}
-----
Example 4 (local variable length array):
-----
import std.stdio;
void main ()
{
int [] a;
ref int [] f ()
{
return a [0..1];
}
a = new int [1];
auto s = f ();
writeln (s);
auto t = f ();
writeln (t);
}
-----
Comment #2 by andrej.mitrovich — 2013-03-07T18:50:47Z
Issue 2486 fixed this.
*** This issue has been marked as a duplicate of issue 2486 ***