use std::fmt::Debug;
fn main() {
let pointer_to_int = &mut 1;
let raw = pointer_to_int as *mut i32;
unsafe { deref_pointer(raw) };
}
unsafe fn deref_pointer<T: Debug>(p: *mut T) {
println!("{:?}", *p)
}Rusts type system provides many guarantees, but sometimes, they make specific solutions hard or impossible.
For that reason, Rust has the concept of "unsafe code".
Unsafe code is allowed to:
freely access memory
dereference raw pointers
call external functions
declare values Send and Sync
write to unsynced global variables
Not unsafe are:
conversion to raw pointers
memory leaks
Unsafe code should never:
be used to manage memory managed by a different allocator (e.g. construct a std:::vec::Vec from a C++ vector and drop it)
cheat on the borrow checker, for example by changing lifetimes or mutability of a type. The most common source of "but I was so sure that works" bugs.
When implementing data structures, unsafe isn’t unusual.
Safe Rust is the worst language to implement linked lists. There’s a full text on this
Unsafe code must always be marked unsafe.
use std::fmt::Debug;
fn main() {
let pointer_to_int = &mut 1;
let raw = pointer_to_int as *mut i32;
unsafe { deref_pointer(raw) };
}
unsafe fn deref_pointer<T: Debug>(p: *mut T) {
println!("{:?}", *p)
}unsafeNot all examples are that simple. unsafe must guarantee the invariants that Rust expects.
This especially applies to ownership and mutable borrowing
unsafe can lead to a value having 2 owners -> double free
unsafe can make immutable data temporarily mutable, which will lead to broken promises and tears.
Rust allows you to shoot yourself in the foot, it just requires you to take your gun out of the holster and remove the safety first.
As Rust forbids aliasing, it is impossible in safe Rust to split a slice into 2 non-overlapping parts.
#[inline]
fn split_at_mut(&mut self, mid: isize) -> (&mut [T], &mut [T]) {
let len = self.len();
let ptr = self.as_mut_ptr();
unsafe {
assert!(mid <= len);
(from_raw_parts_mut(ptr, mid),
from_raw_parts_mut(ptr.offset(mid), len - mid))
}
}Will highlight which function calls are unsafe inside an unsafe block
Helpful for longer unsafe blocks
{
"editor.semanticTokenColorCustomizations": {
"rules": {
"*.unsafe:rust": "#ff00ff"
}
}
}