d语言的改进:默认不抛与安全
加抛为函数属性
理由
当前,默认情况下允许函数引发异常.可以通过应用不抛属性来更改此行为.但一旦不抛在模块域或块中使用,其域中的所有函数都会受到影响;
因此聚合不继承从外部域的不抛属性.如需要整个模块不抛,那么该属性不仅必须在模块域内应用,而且必须在每个聚合的定义内应用:
空 栏(); //可抛
struct S1 {
不抛 void foo(){bar();}//错误,bar()抛
}
不抛{
struct S2{
void foo(){bar();}//正确,因为未应用`不抛`
}
}
问题是,即使在永不抛的代码中,异常成本很高.因此,异常应该是选进,而不是选出.尽管此DIP不建议启用异常,但抛属性是其关键要求.该属性对文档也有帮助,是的,函数确实可抛.
先前工作
@安全,@信任和@系统属性可互相覆盖.
描述
加抛到属性.加抛到函数属性.这与抛语句的开头有歧义, 但可向前看是否式后有个声明来消歧.
该属性仅适用于函数和闭包类型,忽略其他类型.如在函数声明中出现,则表明该函数可抛出异常.
空 bar()抛 ;
struct S1 {
不抛 void foo(){bar();}//错误,bar()抛
}
struct S2 {
void foo(){bar();} //正确
}
不能同时抛且不抛,但可在闭域内相互覆盖:
空 abc()抛 抛 ; //错误
void bar()抛 不抛 ; //错误
不抛:
foo()抛 ; //好
抛:
def()不抛 ; //好
语法变化
加抛到函数属性:
函数属性:
- 抛
不抛
纯
属性
重大变更和弃用
无
参考
Herb Sutter在"去碎片化的C++"的使异常更便宜且有用中说:“一半以上C++用户在C++代码中全部或部分禁止了异常”.
将@安全设为默认值
当前,D函数默认为@系统.本DIP建议将默认值改为@安全.
理由
最初开发D时,几乎不额外检查安全@安全.但,随着不安全代码的成本越来越明显和昂贵,且@安全函数越来越强大,平衡已发生了变化.用户期望默认安全,而不是相反.
先前工作
其他语言(如Rust和C#)具有安全性,可选出而不是选进.
描述
当前未注解函数(例如模板函数,嵌套函数和λ)具有@安全/@系统属性.此行为不变.而现在所有其他未注解函数默认为@安全而不是@系统.
由于会破坏很多现有代码,可用编译器开关启用它:
-preview=默认安全,无语法变化.
重大变更和弃用
很可能会影响大量未注解@安全,@信任或@系统的代码.幸运的是,方法很简单,尽管很麻烦:用@信任或@系统注解不安全的函数.
浙公网安备 33010602011771号