Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

不被视为 unsafe 的行为

Rust 编译器不认为以下行为是_不安全的_,尽管程序员可能(应该)认为它们是不受欢迎的、意外的或错误的。

  • 死锁
  • 内存和其他资源泄漏
  • 不调用析构器就退出
  • 通过指针泄漏暴露随机化基地址

整数溢出

如果程序包含算术溢出,则程序员犯了错误。在以下讨论中,我们保持算术溢出和包装算术之间的区别。第一个是错误的,而第二个是有意的。

当程序员启用了 debug_assert! 断言时(例如,通过启用非优化构建),实现必须插入在溢出时 panic 的动态检查。其他类型的构建可能导致 panic 或溢出时静默包装的值,由实现自行决定。

在隐式包装溢出的情况下,实现必须通过使用二进制补码溢出约定提供明确定义的(即使仍被视为错误的)结果。

整数类型提供固有方法,允许程序员显式执行包装算术。例如,i32::wrapping_add 提供二进制补码包装加法。

标准库还提供了一个 Wrapping<T> 新类型,确保 T 的所有标准算术操作都具有包装语义。

有关错误条件、理由和有关整数溢出的更多详细信息,请参阅 RFC 560

逻辑错误

安全代码可能施加额外的逻辑约束,这些约束既不能在编译时也不能在运行时检查。如果程序违反此类约束,行为可能未指定,但不会导致未定义行为。这可能包括 panic、错误结果、中止和不终止。行为也可能在运行、构建或构建类型之间有所不同。

例如,实现 HashEq 要求被认为相等的值具有相等的哈希值。另一个示例是 BinaryHeapBTreeMapBTreeSetHashMapHashSet 等数据结构,它们描述了键在数据结构中的修改约束。违反此类约束不被视为不安全,但程序被视为错误,其行为不可预测。