www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19111] New: Returning a reference to local array results in

https://issues.dlang.org/show_bug.cgi?id=19111

          Issue ID: 19111
           Summary: Returning a reference to local array results in
                    garbage
           Product: D
           Version: D2
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: alex sunopti.com

See code below.
This is a reduction of a real life bug.
Arrays declared like int[10] a, appear to behave differently to auto a = new
int[10].
I can understand this might be intended for efficiency etc, but it is source of
undefined behaviour that I thought D design intent was to avoid.

In the below, the code can work as long as makeRef happens to modify the array
in a way that makes it need to reallocate the array on the heap.
If that doesn't happen, a reference is returned to the local variable.
With my previous understanding of how arrays were garbage collected, nice to
slice etc it is really not clear that it is possible to return a reference to a
locally declared variable that can go out of scope.

I suggest that int[10] should be on the heap unless the compiler can be sure
that there isn't a way for a reference to escape.
That way people writing high performance code that actually need a stack array
have to write code in a way that convinces the compiler not to promote it to
the stack, and everyone else gets the code that avoids undefined behavior.


import std.stdio;

int[] makeRef(int[] a)
{
        a ~= 43;   //if this is removed the result of getArray contains
garbage.
        return a;
}

int[] getArray()
{
        int[10] a;
        a []= 42;
        //return a[0..3];       //Error: returning cast(int[])a escapes a
reference to local variable a
        return makeRef(a);      //compiles without error, and returns garbage,
unless makeRef happens to modify a
}

void main()
{
        writefln("%s",getArray());
}

--
Jul 22 2018