d使引用计数析构器为@safe打破了DIP1000
原文
如果设置std.conv.RefCounted的析构器为@safe,则下面的代码用-preview=dip1000成功编译,但不应如此.如果使用中域而不是域容器局部,它编译正确的不,但用户不应手动.编译器不应编译逃避局部引用的易错代码.参考
import std.stdio;
import std.typecons;
struct Container
{
int[] data;
}
void main ()
{
auto ptr = getPtr();
writeln(ptr);
const save = ptr.dup;
auto other = getPtr();
assert(save == ptr);
}
int[] getPtr ()
{
int[42] local;
return getPtr2(Container(local));
}
int[] getPtr2 (scope Container local)
{
RefCounted!Container rc = local;
return rc.refCountedPayload().data;
}
能简化为不导入Phobos的独立测试用例吗?
因为按@system推导引用计数的析构造器,顶部添加@safe:会停止编译.
用2.098和-dip1000,也检测到逃逸引用计数构造器的局部变量.
在@safe似乎不可能逃逸本地静态数组,所以该问题似乎不再有效?
但是,对上面拉请目标,即使解决引用计数实现中的问题,引用计数切片(即使是变相)也不能使析构器@safe,因为:
void test() @safe {
auto slice = makeSomeKindOfRefCountedSlice!int(10);
int[] local = slice.payload.data;
static assert(!__traits(compiles, &slice)); // 域
static assert(!__traits(compiles, &local)); // 域
slice = slice.init; // 0并释放
local[1] = 32; // 在@safe函数中用后释放
}
需要定义仅返回临时变量函数的方法(这样不会编译上面的int[]local=slice.payload.data行).在可以之前,该类引用计数切片的@safe析构器仅按惯例是安全的(即,要点?)
浙公网安备 33010602011771号