Nasty corner case behaviour
Meta
jared771 at gmail.com
Fri Apr 19 23:42:53 UTC 2019
On Thursday, 18 April 2019 at 05:01:17 UTC, H. S. Teoh wrote:
> Got bitten by this today:
>
> import std.algorithm : filter, map;
> import std.stdio;
>
> struct S {
> bool flag;
> auto method() {
> return [ 1 ].filter!(e => flag);
> }
> }
>
> void main() {
> auto s = S(true);
> writeln(s.method);
>
> auto arr = [ s ];
> writeln(arr[0].method);
>
> auto mappedArray = arr.map!(e => e.method);
> writeln(mappedArray.front);
> writeln(mappedArray);
> }
>
> Expected output:
>
> [1]
> [1]
> [1]
> [[1]]
>
> Actual output:
>
> [1]
> [1]
> [1]
> [[]]
>
> Exercise for the reader: explain the problem.
>
> Hint: it's not a bug in Phobos.
>
> If method() is changed to the following, the problem goes away:
>
> auto method() {
> auto _flag = flag;
> return [ 1 ].filter!(e => _flag);
> }
>
> It should be obvious by now that the problem is caused by the
> lambda incorrectly closing over a member variable in a struct
> instance that subsequently goes out of scope, while the
> returned closure lives on. Unfortunately, neither -dip25 nor
> -dip1000 catches this leakage, even if main() is marked @safe.
>
>
> T
I find this one a bit confusing. Shouldn't the struct be moved to
the heap when the compiler detects that it's being closed over?
More information about the Digitalmars-d
mailing list