天天看點

d嵌套類懸空引用域外結構

import std.algorithm :, map;
import std.stdio;

struct S {
    bool flag;
    auto method() {
        return [ 1 ].filter!(e => flag);
    }
}

void main() @safe {
    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);
}
//期望:
    [1]
    [1]
    [1]
    [[1]]

//實際
    [1]
    [1]
    [1]
    [[]]      

如下修改,可去掉:

auto method() {
    auto _flag = flag;
    return[1].filter!(e=>_flag);
}      

更改​

​flag​

​​為整數值并​

​列印​

​​該值,表明在最後​

​writeln​

​​中,​

​該值​

​​已損壞為垃圾值.

似乎​​

​λ​

​​錯誤地關閉了結構​

​臨時​

​​副本(​

​map​

​​參數作為​

​局部變量​

​​),執行​

​λ​

​​時該副本已出域.把​

​.flag​

​​顯式複制到​

​method()​

​​中的局部變量,似乎會使它​

​正确​

​​的在​

​堆上​

​​配置設定.

即使按​​

​@safe​

​​标記​

​main()​

​​,使用​

​-dip25-dip1000​

​編譯也無法解決該問題.

auto makeI(int m) @safe
{
    static struct S
    {
        int m;
        auto inner()
        {
            class I
            {
                auto get() @safe { return m; }
            }
            return new I;
        }
    }
    scope s = S(m);
    return s.inner();
}

void main() @safe
{
    auto i = makeI(5);

    function()
    {
        // clean stack
        pragma(inline, false);
        long[0x500] a = 0;
    }();

    assert(i.get() == 5);
}      

繼續閱讀