25.1 The Unsafe Superset
Safe Rust operates under strict rules (ownership, borrowing, lifetimes, type safety) to prevent undefined behavior (UB). Unsafe Rust provides access to five additional capabilities, sometimes called “unsafe superpowers,” that bypass certain checks:
- Dereferencing raw pointers (
*const T
and*mut T
). - Calling
unsafe
functions (including external functions declared via FFI). - Accessing or modifying
static mut
variables. - Implementing
unsafe
traits. - Accessing fields of
union
s.
Crucially, entering an unsafe
context does not disable all of Rust’s safety mechanisms. The borrow checker still operates, ownership rules apply, and type checking is still performed. The unsafe
keyword only permits these five specific actions within an unsafe
block or function. The responsibility shifts to the programmer to ensure these actions do not violate Rust’s memory safety invariants (e.g., avoiding data races, dangling pointers, invalid pointer arithmetic).
25.1.1 Why Unsafe Rust is Necessary
Despite Rust’s emphasis on safety, the unsafe
mechanism is essential for its role as a systems programming language:
- Hardware Interaction: Direct memory-mapped I/O, register manipulation, or executing specific CPU instructions often requires bypassing safe abstractions.
- Foreign Function Interface (FFI): Interacting with libraries written in C or other languages involves calling code that Rust’s compiler cannot analyze or verify.
- Low-Level Data Structures: Implementing certain efficient data structures (e.g., some variants of linked lists, custom allocators, lock-free structures) may require pointer manipulations that are difficult or impossible to express within safe Rust’s constraints.
- Performance Optimization: In specific, performance-critical sections, manual memory management or pointer operations might offer optimizations beyond what the compiler or safe abstractions provide, although this is less common than the other reasons.
In these situations, the compiler cannot guarantee safety, so the unsafe
keyword marks the boundaries where the programmer asserts the code’s correctness regarding Rust’s safety rules.