Unsafe Rustの関数

未定義動作を避けるために特定の事前条件が必要な場合は、自分の関数を unsafe としてマークできます。

// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

/// 与えられたポインタが指す値を入れ替えます。
///
/// # Safety
///
/// ポインタは有効で、適切にアラインされており、関数呼び出しの間は
/// それ以外の方法でアクセスされていてはなりません。
unsafe fn swap(a: *mut u8, b: *mut u8) {
    // SAFETY: 呼び出し元は、ポインタが有効で適切にアラインされており、
    // ほかにアクセスがないことを保証しています。
    unsafe {
        let temp = *a;
        *a = *b;
        *b = temp;
    }
}

fn main() {
    let mut a = 42;
    let mut b = 66;

    // SAFETY: これらのポインタは参照から得られたものなので、有効で、
    // アラインされており、排他的でなければなりません。
    unsafe {
        swap(&mut a, &mut b);
    }

    println!("a = {}, b = {}", a, b);
}

実際には、swap 関数でポインタを使うことはありません — 参照を使えば安全に実装できます。

Rust 2021 以前では、unsafe 関数内では unsafe ブロックなしで unsafe なコードを使えることに注意してください。これは 2024 エディションで変更されました。古いエディションでは #[deny(unsafe_op_in_unsafe_fn)] を使ってこれを禁止できます。追加して、どうなるか試してみてください。