CodeBlanks Logo Icon CodeBlanks

unsafe block

Learn what the unsafe block allows.

The unsafe block

Five operations the compiler can't prove safe can only be done inside unsafe: dereferencing a raw pointer, calling an unsafe fn, accessing a static mut, implementing an unsafe trait and reading a union field. unsafe doesn't turn off the borrow checker; it only allows these five operations and leaves responsibility for correctness to you:

let mut x = 5;
let p = &mut x as *mut i32;   // creating a raw pointer is safe
unsafe {
    *p += 1;                  // dereferencing it is unsafe
}
println!("{x}");              // 6

unsafe means a promise: "I guarantee this block follows the rules."

Why does unsafe exist?

Some valid programs are too complex for the compiler to prove: operating system calls, hardware access, performance-critical data structures. Standard library types like Vec, String and Mutex use unsafe internally but offer a safe interface to the outside. That is always the goal: keep unsafe inside a small, documented, safe abstraction.

// // SAFETY: p points to a valid, aligned i32;
// // no other reference is in use at the same time.
unsafe { *p += 1; }

Practice Increment through a raw pointer

Create a *mut i32 raw pointer for let mut x = 5;, increment it by 1 in an unsafe block and print x.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
fn main() {
    let mut x = 5;
    let p = &mut x as *mut i32;
    unsafe {
        *p += 1;
    }
    println!("{}", x);
}

Expected output

6

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Does the borrow checker run inside an <code>unsafe</code> block?

  • No, it's fully off
  • Only for references
  • Only in debug
  • Yes; only five special operations are additionally allowed Correct answer

Explanation: References are subject to the same rules inside unsafe; raw pointers aren't checked anyway.

2 Unsafe block

Question
let p = &mut x as *mut i32;
____ {
    *p += 1;
}
Answer
let p = &mut x as *mut i32;
unsafe {
    *p += 1;
}

Explanation: Dereferencing a raw pointer requires an unsafe block.

3 Operation and requirement

Term Meaning
&x as *const i32 Safe
*p (ham) Needs unsafe
unsafe fn call Needs unsafe (call)
// SAFETY: yorumu Justification note

All lessons in Advanced