[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