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.
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.
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.
// 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.
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)) } }}
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.
Explore Topics
Professional Web Designing Services
- Responsive Websites
- E-commerce Solutions
- SEO Friendly Design
- Fast & Secure
- Support & Maintenance