On 06/04/2013 09:19 PM, Idan Arye wrote:
Consider the following code. What will it print?

     auto arr=new ulong delegate()[5];

     foreach(i;0..arr.length){
         arr[i]=()=>i;
     }

     writeln(arr.map!`a()`());

It is natural to expect that it will print [0, 1, 2, 3, 4], but it
actually prints [5, 5, 5, 5, 5]. The reason is obvious - all the
delegates refer to the same `i` in their closures, and at the end of the
loop that `i` is set to `5`.

...

It is not that obvious. They refer to different i's that happen to reside at the same place in the stack frame. It's a bug.

It is more obvious that it is a bug given this code snippet:

import std.stdio, std.algorithm;

void main(){
    auto arr=new ulong delegate()[5];
    foreach(immutable i;0..arr.length){
         arr[i]={auto j=i;return {assert(j==i); return i;};}();
    }
    writeln(arr.map!`a()`());
}

As you can see, 'i' mutates even though it is declared immutable.

...

Yes. Yes.

http://d.puremagic.com/issues/show_bug.cgi?id=2043

Reply via email to