CodeBlanks Logo Icon CodeBlanks

unsafe fn

Define and call unsafe fn.

unsafe fn

An unsafe fn is a function with a contract the caller must keep and the compiler can't check. The contract is written in a doc comment headed # Safety; the call site needs an unsafe block:

/// Reads the value the pointer points to.
///
/// # Safety
/// `p` must point to a valid, aligned and initialized `i32`.
unsafe fn oku(p: *const i32) -> i32 {
    unsafe { *p }
}

let x = 7;
let n = unsafe { oku(&x) };

Examples in the standard library: get_unchecked, from_utf8_unchecked, slice::from_raw_parts.

A safe wrapper

Putting the unsafe call inside a safe function and keeping the contract there frees the user from unsafe:

fn toplam_hizli(v: &[i32]) -> i32 {
    let mut t = 0;
    for i in 0..v.len() {
        // SAFETY: i < v.len() comes from the loop range.
        t += unsafe { *v.get_unchecked(i) };
    }
    t
}

The function itself is safe: whatever slice it's called with, no undefined behaviour can occur.

Practice Safe wrapper

Write a documented unsafe fn oku(p: *const i32) -> i32 and the safe toplam_hizli function above. Print the results of oku(&x) for let x = 7; and toplam_hizli for [1, 2, 3, 4] separated by a space.

Starter code

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

Sample solution

main.rs
/// İşaretçinin gösterdiği değeri okur.
///
/// # Safety
/// `p` geçerli, hizalı ve başlatılmış bir `i32`'ye işaret etmelidir.
unsafe fn oku(p: *const i32) -> i32 {
    unsafe { *p }
}

fn toplam_hizli(v: &[i32]) -> i32 {
    let mut t = 0;
    for i in 0..v.len() {
        // SAFETY: i < v.len() döngü aralığından gelir.
        t += unsafe { *v.get_unchecked(i) };
    }
    t
}

fn main() {
    let x = 7;
    let n = unsafe { oku(&x) };
    println!("{} {}", n, toplam_hizli(&[1, 2, 3, 4]));
}

Expected output

7 10

Questions and answers

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

1 When can <code>get_unchecked(i)</code> be used safely?

  • Only in release
  • When it's known for sure by other means that i is within bounds Correct answer
  • Always
  • Never

Explanation: If the loop is over 0..v.len(), the bound is already proven; still, the compiler often removes the bounds check itself, so measure first.

2 Unchecked access

Question
t += unsafe { *v.____(i) };
Answer
t += unsafe { *v.get_unchecked(i) };

Explanation: get_unchecked does no bounds check; the contract is on the caller.

3 Item and meaning

Term Meaning
unsafe fn Function with a contract
# Safety Contract documentation
// SAFETY: Where the contract is met
Safe wrapper Hides the unsafe

All lessons in Advanced