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

Reply via email to