d纯函数可通过异常逃逸参数
原文
纯函数可通过异常逃逸参数
修复阻止了通过返回值逃逸,但还有限制:即使无法通过参数或返回值逃逸,仍可把纯函数参数放入异常并抛.
void f_throw(string x) @safe pure
{
throw new Exception(x);
}//异常.
void escape_throw_20150() @safe
{
immutable(char)[4] str;
f_throw(str[]);
}
如果函数可抛,就不应有纯->域.
问题在,因为它是纯函数,纯禁止在全局变量中存储内容,假定x不能逃逸.编译器为x参数自动推导的域.
问题是未考虑通过抛出异常来逃逸.
纯函数抛参数应仅是个错误
太多现有代码依赖推断域,且(可能)很少抛参数.
对确实中断代码,方法是制作参数副本,然后抛副本.这是可行的,因为域不是可传递的.
阻止修复PR的是excel-D(shouldEqual)和一些Phobos单元测试中的1个函数,如何向用户解释?
void enforce(bool x, string msg) @safe pure
{
if (!x)
throw new Exception(msg);
}
编译器会无缘无故要求造msg串副本.现在(如在Phobos中),考虑返回第一个参数的变体.
int* enforce(int* x, string msg) @safe pure
{
if (!x)
throw new Exception(msg);
return x;
}
因为返回值现在有了指针,消息不会从纯推断域,所以编译器要么:
-允许它,即更改返回类型导致关于抛出消息的奇怪的无关错误
-仍然报错,即必须复制消息,且仍不能分配域串给参数!
最后,考虑给出自动返回类型:
auto enforce(bool x, string msg)
{
if (!x)
throw new Exception(msg);
}
如何推断属性?
1,不纯@system.2,不纯@safe.3,纯@system.
选择@safe吗?如果我明确指定pure,它会推断@system吗?
看起来是特例,但有复杂连锁反应,不是好主意.
浙公网安备 33010602011771号