Bug 9651 – Returning a newly-created slice by reference

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-03-05T12:00:00Z
Last change time
2013-03-07T18:50:47Z
Keywords
accepts-invalid
Assigned to
nobody
Creator
gassa
See also
http://d.puremagic.com/issues/show_bug.cgi?id=4451

Comments

Comment #0 by gassa — 2013-03-05T12:00:51Z
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 ***