Delegate is left with a destroyed stack object

Timon Gehr timon.gehr at gmx.ch
Wed Oct 30 13:48:50 PDT 2013


On 10/30/2013 10:56 AM, David Nadlinger wrote:
> On Wednesday, 30 October 2013 at 09:20:40 UTC, Lionello Lunesu wrote:
>> Why? It's a struct. It should be completely fine to create a copy [on
>> the heap] for the closure context
>
> That's definitely not how D closures work, they always refer to local
> variables "by reference".
>
> One other place where this tends to crop is for code involving loop
> variables, but while the behavior might be unexpected to some,
> discussion has made clear that the code works as intended:
>
> ---
> void main() {
>    import std.stdio;
>
>    void delegate()[] dgs;
>    foreach (i; 0 .. 5) dgs ~= { writeln(i); };
>
>    foreach (dg; dgs) dg();
> }
> ---
>
> If structs behaved like you want them to, the snippet would (have to)
> print 0, 1, 2, 3, 4 as well, and tht's definitely too big a language
> change to consider at this stage.
>
> David

No, the current behaviour is an implementation bug and the expected 
behaviour is indeed to print the numbers from zero to four. The foreach 
iteration variable is stored in loop iteration scope since 2.063. The 
frontend never allocates closures in such a scope even though it is 
required for basic type safety.

Bug report: http://d.puremagic.com/issues/show_bug.cgi?id=2043
Past discussion: 
http://forum.dlang.org/thread/felqszcrbvtrepjtfpul@forum.dlang.org

Your example can be changed to use a for loop, and then it indeed 
illustrates your point.

for(int i=0;i<5;i++) dgs ~= { writeln(i); };
foreach (dg; dgs) dg(); // prints 5 five times


More information about the Digitalmars-d mailing list