例: may_overflow 関数
// Copyright 2026 Google LLC // SPDX-License-Identifier: Apache-2.0 /// 負の数に 2^31 - 1 を加えます。 unsafe fn may_overflow(a: i32) -> i32 { a + i32::MAX } fn main() { let x = unsafe { may_overflow(123) }; println!("{x}"); }
「unsafe キーワードは、一部の人が想定しているものとは微妙に異なる意味を持つことがあります。」
「コードの作者は、そのコードが正しいと考えています。原則として、そのコードは安全です。」
「このおもちゃの例では、may_overflow 関数は負の数に対してのみ呼び出されることを意図しています。」
学習者に、なぜ may_overflow に unsafe キーワードが必要なのか説明できるか尋ねてください。
「何が問題なのかよくわからない場合は、ここで少し立ち止まって説明しましょう。i32 では、正の数に使えるのは 31 ビットだけです。演算によって 31 ビットを超える結果が生成されると、プログラムは不正な状態に置かれます。そして、これは単なる数値上の問題ではありません。コンパイラは、不正な状態は起こりえないという前提でコードを最適化します。その結果、コードパスが削除され、実行時の挙動が不安定になるだけでなく、セキュリティ脆弱性も導入されます。」
コードをコンパイルして実行し、panic が発生することを確認してください。次に、playground でこの例を --release モードで実行し、未定義動作を引き起こしてください。
「このコードは正しく使用できますが、不適切な使用は非常に危険です。」
「そして、その使用が正しいことをコンパイラが検証するのは不可能です。」
これが、unsafe キーワードがメモリ安全性の責任がコンパイラからプログラマへ移る場所を示す、と私たちが言うときの意味です。