More range woes: composed ranges are unsafe to return from functions

Timon Gehr timon.gehr at gmx.ch
Tue Oct 16 16:09:09 PDT 2012


On 10/17/2012 12:11 AM, Jonathan M Davis wrote:
> On Wednesday, October 17, 2012 00:04:49 Timon Gehr wrote:
>> On 10/16/2012 09:47 PM, jerro wrote:
>>>> Hmm. There *is* a delegate being passed to map(). Would that cause
>>>> problems? Theoretically it shouldn't, but as you said, if dmd isn't
>>>> handling it correctly that could cause problems.
>>>
>>> I'm looking at the disassembly of cprod (http://pastebin.com/ngTax6B8)
>>> and there doesn't seem to be a call to _d_allocmemory in it. AFAIK it
>>> should be if the memory for the variables that the delegate uses was
>>> allocated on the heap?
>>
>> It should certainly allocate a closure. However, we don't want hidden
>> allocations in Phobos, so an alternate implementation strategy that
>> captures the input by value would be preferable anyway.
>> The bug should be reported in each case.
>
> The allocation of closures is pretty much inevitable when we have delegates
> and/or non-static Voldemort types.
>
> - Jonathan M Davis
>

Unless there are compiler bugs of course. Anyway, that is why I was
suggesting to use an alternate implementation strategy.

The following code is free of allocations if the compiler implementation 
is correct:

auto cprod(R1,R2)(R1 A, R2 B) {
     return zip(sequence!"n"(cast(size_t)0), A.save, B.save, repeat(A), 
repeat(B))
         .map!(function(a) => chain(
               zip(repeat(a[1]), take(a[4].save,a[0])),
               zip(take(a[3].save,a[0]+1), repeat(a[2]))
         )).joiner;
}

It also works around the issue. (note that I got rid of some UFCS
calls. The reason is that we don't know whether R1 and/or R2 actually 
have a member named 'take' or 'repeat' that would hijack the function we
want to call.)


(But you also need to (potentially) escape them in order to trigger the
allocation, so delegates and non-static structs are even useful when
allocating is not an option.)



More information about the Digitalmars-d mailing list