@safe:
class Bar
{
int delegate() dg;
this(int delegate() @safe dg) { this.dg = dg; }
}
struct Foo
{
int i;
Bar bar;
this(int i)
{
this.i = i;
this.bar = new Bar({ return this.i; }); //指向局部this,要改的话改成这样this.i=>i就完了
}
}
Foo getFoo(int i) { return Foo(i); }
//this指向过时的栈桢
//Foo自身未保存在闭包中,只保存了一个指针
void main() {
auto foo = getFoo(5);
getFoo(6);//从寄存器中返回
assert(foo.bar.dg() == 5);
}
这种微妙的栈崩溃
的问题,就是dip1000
要解决的.{ return this.i; }
是堆上分配的闭包.Foo
可放在寄存器
中,问题
就是this
指针,但this
现在已经没了,指向垃圾
了.Foo
放在哪?从寄存器
中返回,然后复制进局部Foo
,此时的this
指针已指向过期栈帧
了.Foo
自身未保存在闭包
中,只是存储Foo
的指针.
如果加成员
给Foo
,则不再从寄存器
中返回,而是通过在调用栈
指向foo
的隐藏指针
返回.这时λ
中的this
始终指向main.foo
,再次调用getFoo
时,对返回值
创建个单独的main._TMP
.但这是由nrvo
优化把foo
放在main()
中,所以this
未过期.
问题,就是this
所指向的东西,已经离开域
了.现在指向
的是垃圾
.dmd -dip1000 %
通过标记@安全
可发现该类错误.