P.SAF.UNS.01 Unsafe 代码应仅在需要的场景下使用
【描述】
- 不要为了逃避编译器安全检查而随便滥用 Unsafe Rust,否则很可能引起未定义行为(UB)。
- 不要为了提升性能而盲目使用 Unsafe Rust。
- 要尽量缩小使用
unsafe
块的范围,而不要将多余的代码都包入unsafe
块中。 - 对于 Unsafe 函数,应该显式地标记
unsafe
,不要试图通过宏等技巧打破 Unsafe 传播链条。 . 不要通过 Unsafe 将不可变引用/指针手工转换为可变引用/指针。这类场景考虑使用内部可变性容 器Cell<T>
或RefCell<T>
。
【反例】
Rust
// 该函数为滥用 unsafe 来跳过 Rust 借用检查
// 强行返回本地变量的引用,最终引起未定义行为
fn abuse_unsafe_return_local_ref<'a>() -> &'a String {
let s = "hello".to_string();
let ptr s addr = &s as *const String as usize;
unsafe {
&*(ptr s addr as *const String)
}
}
fn main() {
let s = abuse_unsafe_return_local_ref(); // error: Undefined Behavior:encountered a dangling reference (use-after-free)
}
【反例】
Rust
// 不符合:使用 unsafe 通过不可变借用修改变量
fn main() {
unsafe fn increase_num(r: &i32) {
*(r as *const i32 as *mut i32) += 1;
}
let num = 0; unsafe {
increase_num(&num); }
println!("{num}");
}