Rust Unsafe Rust Cheat Sheet
The five unsafe superpowers, raw pointers, FFI, and the invariants you must uphold manually when the borrow checker steps aside.
2 PagesAdvancedFeb 26, 2026
The Five unsafe Superpowers
unsafe only enables these; it does NOT disable the borrow checker elsewhere.
- dereference raw pointers- *const T / *mut T can be dereferenced
- call unsafe functions- including FFI functions and unsafe trait methods
- access/modify mutable statics- static mut (increasingly discouraged, use Atomic* or Cell types)
- implement unsafe traits- e.g. Send, Sync when the compiler can't verify them
- access union fields- reading a union field requires unsafe
Raw Pointers
Unlike references, raw pointers can be null, dangling, or unaligned — creating them is safe, dereferencing is not.
rust
let mut x = 5;let r1 = &x as *const i32; // creating a raw pointer is safelet r2 = &mut x as *mut i32;unsafe { println!("{}", *r1); // dereferencing requires unsafe *r2 = 10;}// From an arbitrary address (dangerous, only do this with a real reason)let address = 0x012345usize;let p = address as *const i32;// unsafe { *p } // undefined behavior unless you KNOW this address is valid
FFI (Foreign Function Interface)
Calling into C, and exposing Rust functions to C.
rust
// Declaring external C functionsextern "C" { fn abs(input: i32) -> i32;}fn call_c() { unsafe { println!("abs(-3) = {}", abs(-3)); }}// Exposing a Rust function to C (no name mangling, C calling convention)#[no_mangle]pub extern "C" fn rust_add(a: i32, b: i32) -> i32 { a + b}
Safe Abstractions Over unsafe
The standard pattern: contain unsafe inside a module, expose a safe API.
rust
pub struct Wrapper<T> { ptr: *mut T, len: usize,}impl<T> Wrapper<T> { pub fn get(&self, index: usize) -> Option<&T> { if index >= self.len { return None; // bounds check happens in safe code } // SAFETY: index < self.len, ptr was allocated for `len` elements // and is non-null (checked at construction). unsafe { Some(&*self.ptr.add(index)) } }}
Pro Tip
Every unsafe block should have a `// SAFETY:` comment directly above it explaining WHY the invariants hold (bounds, alignment, non-null, no aliasing) — this is community convention (and a Clippy lint, undocumented_unsafe_blocks) precisely because unsafe code is only as trustworthy as the reasoning behind it.
Was this cheat sheet helpful?
Explore Topics
#RustUnsafeRust#RustUnsafeRustCheatSheet#Programming#Advanced#TheFiveUnsafeSuperpowers#RawPointers#FFI#Foreign#CheatSheet#SkillVeris