[Issue 21929] New: delegates capture do not respect scoping

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue May 18 16:45:04 UTC 2021


https://issues.dlang.org/show_bug.cgi?id=21929

          Issue ID: 21929
           Summary: delegates capture do not respect scoping
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: deadalnix at gmail.com

See sample code:

https://issues.dlang.org/show_bug.cgi?id=2043

int main() {
    void delegate()[] dgs;

    for (int i = 0; i < 10; i++) {
        dgs ~= () {
            import std.stdio;
            writeln(i);
        };
    }

    dgs ~= () {
        import std.stdio;
        writeln("With cached variables");
    };

    for (int i = 0; i < 10; i++) {
        int index = i;
        dgs ~= () {
            import std.stdio;
            writeln(index);
        };
    }

    foreach (ref dg; dgs)  {
        dg();
    }

    return 0;
}

It outputs:

10
10
10
10
10
10
10
10
10
10
With cached variables
9
9
9
9
9
9
9
9
9
9

While the series of 10 is expected, as the same variable is captured every
time, the series of 9 is not. A new variable is declared with each iteration of
the loop, and therefore a new closure ought to be created.

Failure to do allows for very strange things to happen, such as observing
mutation in immutable variables.

The expected output would be:

10
10
10
10
10
10
10
10
10
10
With cached variables
0
1
2
3
4
5
6
7
8
9

That semantic is consistent with what is done in other languages, such as C#:
https://unicorn-dev.medium.com/how-to-capture-a-variable-in-c-and-not-to-shoot-yourself-in-the-foot-d169aa161aa6
(link provided courtesy of Andrei Alexandrescu).

Possibly related issue: https://issues.dlang.org/show_bug.cgi?id=2043

I decided to open a new one because the discussion in the old one refers to a
ton of outdated language constructs and is therefore not super helpful.

--


More information about the Digitalmars-d-bugs mailing list