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)
}
unsafe
Not 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"
}
}
}