​原文​​​ 最新101.0版本dmd​​可接受​​以下代码:

int global;
int* foo(scope int* p)@safe{
auto dg=(return scope int* q)@safe return scope{
return p;
};
return dg(&global);
}

auto qux()@safe{
int x=10;
int* p=&x;
int* q=foo(p);
return q;
}

void main()@safe{
import std.stdio;
auto p=qux();
version(SMASH_STACK) writeln("粉碎栈");
writeln(*p);
}

化简为:

int global;
int* foo(scope int* p)@safe{
auto dg=(return scope int* q)@safe return scope{
return p;
};
return dg(&global); <== 返回p的指针
}

这不是问题,因为​​编译器​​​可识别p的​​逃逸​​​,并在堆的​​闭包​​​中分配​​p​​​.每当​​嵌套函数​​​变成​​闭包​​​时,就​​堆分配​​​.
对没有转换成​​​闭包​​​的​​嵌套函数​​​,在​​堆分配​​​的闭包中放​​p​​​,并对​​'return dg(&global);​​产生一个错误.

第一个示例在​​'@safe'​​​代码中​​逃逸​​​了​​死栈变量​​​引用.当然是个​​问题​​.

在堆上分配有个指向​​'x'​​​栈变量指针的​​'scope int*p'​​​的​​闭包环境​​​.
​​​'qux'​​​使用​​'foo'​​​来​​逃逸​​​局部​​'x'​​​栈变量指针.当​​UB​​​时,不再​​引用​​​闭包环境.​​'foo'​​​只是允许​​'域'​​​来清洗任意指针的工具.​​'域'​​​指针进,​​非'域'​​指针出.