TL;DR
言語の規則に反するので、プログラムを正しくないものにする振る舞い。Rust のリファレンスでは、データ競合やダングリングポインタへのアクセスなどが挙げられている。
なぜ必要か
Rust のリファレンスによると、未定義動作を起こすコードは、unsafe ブロックの中であっても正しくない。unsafe は、未定義動作を避ける責任がプログラマにあることを示すだけで、Rust のプログラムが未定義動作を起こしてはならないという事実は変わらない。何が未定義動作かを知らないと、Unsafe Rust を安全に書けない。
仕組み
Rust のリファレンスは、未定義動作になる振る舞いを列挙している。たとえば次のものがある。
- データ競合
- ダングリングポインタや、アラインメントが合わないポインタを通じたアクセス
&Tが生きている間に、その参照先を書き換えるといったエイリアシング規則の違反- 不正な値を作ること(
boolが0と1以外の値を持つなど) - 間違った呼び出し規約で関数を呼ぶことや、巻き戻せないスタックフレームを越えて巻き戻すこと
unsafe なコードを書くときは、そのコードとやり取りする安全なコードが、これらの振る舞いを起こせないようにしなければならない。これを満たすコードを sound、満たさないコードを unsound と呼ぶ。
注意点
リファレンスは、この一覧が網羅的ではなく、増えたり減ったりしうると断っている。一覧にないからといって安全とは限らない。