The lifetime of reduce's internal seed

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Apr 22 11:17:57 PDT 2014


On 04/22/2014 11:03 AM, monarch_dodra wrote:

 > On Tuesday, 22 April 2014 at 17:31:22 UTC, Ali Çehreli wrote:
 >> I opened the following bug before reading reduce's documentation
 >> carefully:
 >>
 >>   https://issues.dlang.org/show_bug.cgi?id=12610
 >>
 >> import std.stdio;
 >> import std.algorithm;
 >>
 >> void main()
 >> {
 >>     int[] arr = [ 0 ];
 >>
 >>     int[1] seed;
 >>     int[] result = reduce!((sum, _) => sum[])(seed, arr);
 >>
 >>     writefln("%s", result);
 >> }
 >>
 >> The output is garbage like [373728176].
 >>
 >> Note that the original seed is a value type, which is later sliced by
 >> the lambda.
 >>
 >> Now I think that it can be considered a user error. Do you agree whit
 >> that? If so, this is something else we should be careful about similar
 >> to the internal buffer of byLine.
 >>
 >> Ali
 >
 > I see one user bug,

Let this thread be a lesson to me (and other mortals) then.

 > and one language bug, but no library issues.
 >
 > The user bug is the lambda, that returns a reference to a local
 > ("sum[]"). That said, I do believe the compiler should be able to catch
 > think.
 >
 > The "int[] reduce...", however, I think is a outright language issue.
 > Implicilty calling opSlice on a static array is one thing, but doing it
 > on an rvalue is an outright aberration. The code should be rejected no
 > questions asked.

I don't think there is slicing an rvalue though. (?) reduce() is taking 
a copy of the seed and then returning a slice to it because the user 
slices it in their lambda. It effectively does the following, which 
unfortunately compiles:

int[] foo()
{
     int[1] sum;
     return sum[];    // <-- no warning
}

void main()
{
     int[] result = foo();
}

The code would be safe if the user gave a slice to reduce(). This brings 
up another concern though: Template authors must watch out for cases 
like the above. There would be cases where we shouldn't simply take a 
copy of a T object and return it.

Ali



More information about the Digitalmars-d-learn mailing list