安全(Safety)
安全,本身是一个相当大的话题。安全性,本身也需要一个局部性的定义。
Rust 的定义中,凡是 可能 会导致程序内存使用出错的特性,都被认为是 不安全的(unsafe)。反之,则是 安全的(safe)。
基于这种定义,C 语言,基本是不安全的语言(它是众多不安全特性的集合。特别是指针相关特性,多线程相关特性)。
根据 Rust 的定义,C 语言几乎是不安全的代名字。但是,从本质上来说,一段程序是否安全,并不由开发它的语言决定。用 C 语言开发出的程序,不一定就是不安全的代码,只不过相对来说,需要花更多的精力进行良好的设计和长期的实际运行验证。Rust 使开发出安全可靠的代码相对容易了。
世界本身是肮脏的。正如,纯函数式语言中还必须有用于处理副作用的 存在一样,Rust 仅凭安全的特性集合,也是无法处理世界的所有结构和问题的。所以,Rust 中,还有 unsafe
部分的存在。实际上,Rust 的 std 本身也是建立在大量 unsafe
代码的基础之上的。所以,世界就是纯粹建立在不纯粹之上,“安全”建立在“不安全”之上。
因此,Rust 本身可以被认为是两种编程语言的混合:Safe Rust
和 。
Unsafe Rust
在 Safe Rust
的所有特性上,只给程序员开放了以下四种能力:
- 对原始指针进行解引(Dereference raw pointers);
- 调用 函数(包括 C 函数,内部函数,和原始分配器);
- 实现
unsafe
traits; - 修改(全局)静态变量。
上述这四种能力,如果误用的话,会导致一些未定义行为,具有不确定后果,很容易引起程序崩溃。
Rust 中定义的不确定性行为有如下一些:
- 对空指针或悬挂指针进行解引用;
- 读取未初始化的内存;
- 破坏指针重命名规则(比如同一资源的
&mut
引用不能出现多次,&mut
与 不能同时出现); - Unwinding 到其它语言中;
- 产生一个数据竞争。
- 死锁;
- 内存泄漏;
- 调用析构函数失败;
- 整数溢出;
- 程序被中断;
- 删除产品数据库(:D);
下面一些链接,给出了安全性更详细的讲解(部分未来会有对应的中文翻译)。