An `unsafe { ... }` block permits operations Rust cannot verify as memory-safe on its own. It does not switch off the borrow checker or make the code safe automatically: the programmer takes responsibility for the operation’s safety. Use it only when needed, and investigate alternatives before using `std::mem::transmute`, which discards type safety. section 5.1
Three situations show why the boundary matters:
- Reinterpreting bits: `unsafe { std::mem::transmute(a) }` treats an `f32` value as a `u32` without changing its underlying bits. section 5.1
- Reading through a raw pointer: `unsafe { *ptr }` permits the dereference, but a pointer to address zero still crashes the memory-scanning program. Starting at address one does not fix it: the scan can still hit memory the process cannot access. section 6.4.2
- Accessing a `static mut`: both reading and writing a mutable global require an unsafe block. A signal handler can use such a global as a flag for the main loop, but avoid global state where possible. section 12.6.1 section 12.12
A small boundary around a pointer read
In a byte-by-byte memory scan, the pointer can be created with `let ptr = i as *const u8;`, while the read is written `let byte_at_addr = unsafe { *ptr };`. The block marks the operation needing programmer scrutiny; it does not establish that `i` names readable memory. section 6.4.2
Listing 5.2 Interpreting a float’s bit string as an integer
fn main() {
let a: f32 = 42.42;
let frankentype: u32 = unsafe {
std::mem::transmute(a) #1
};
println!("{}", frankentype); #2
println!("{:032b}", frankentype); #3
let b: f32 = unsafe {
std::mem::transmute(frankentype)
};
println!("{}", b);
assert_eq!(a, b); #4
}
Follow the `f32`-to-`u32` conversion and back to see where the bit reinterpretations need unsafe blocks. section 5.1
Listing 6.12 Attempting to scan a running program’s memory byte by byte
1 fn main() {
2 let mut n_nonzero = 0;
3
4 for i in 0..10000 {
5 let ptr = i as *const u8; #1
6 let byte_at_addr = unsafe { *ptr }; #2
7
8 if byte_at_addr != 0 {
9 n_nonzero += 1;
10 }
11 }
12
13 println!("non-zero bytes in memory: {}", n_nonzero);
14 }
Notice that an unsafe pointer read can compile yet crash when the scan starts at address zero. section 6.4.2


