www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 8621] New: Iterattion variable in foreach not closed upon properly in delegate

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8621

           Summary: Iterattion variable in foreach not closed upon
                    properly in delegate
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: andrei metalanguage.com



02:49:47 PDT ---
Consider:

import std.stdio;

void main() {
    void delegate()[] a;
    foreach (i; 1 .. 10) {
        a ~= { writeln(i); };
    }
    foreach (f; a) {
        f();
    }
}

This program prints an arbitrary value every run, which means i is not properly
closed upon.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 05 2012
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8621


entheh cantab.net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |entheh cantab.net



Here's more code which I think exhibits the same bug, and also demonstrates
some workarounds and some more info on the nature of the bug.

This code breaks with 2.060 on Windows, compiling with no switches at all, just
"dmd filename.d". The production code I derived it from was fine on 2.059.

------------

import std.stdio;

void main() {
    broken();
    reffix();
    noclosefix();
}

void broken() {
    foreach (z; 0..1) {
        writeln(z);    //Corrupt
        () {writeln(z);} ();    //Corrupt (same value)
    }
}

//The above demonstrates that the variable is broken both inside and outside
the closure.

//Adding 'ref' fixes it:
void reffix() {
    foreach (ref z; 0..1) {
        writeln(z);    //0
        () {writeln(z);} ();    //0
    }
}

//It only breaks if 'z' is closed into the lambda:
void noclosefix() {
    foreach (z; 0..1) {
        writeln(z);    //0
        int z2=z;
        () {writeln(z2);} ();    //0
    }
}

------------

The sort of corrupt values I see for z are for example
28835840 = 0x01B80000
29949952 = 0x01C90000
38535168 = 0x024C0000
36110336 = 0x02270000
But it's always the same between one writeln and the other.

Also breaks with foreach_reverse.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 17 2012