Unsafe Rust的计算机科学边界
原理
unsafe 块关闭五项编译器安全检查:
- 解引用裸指针(
*const T,*mut T) - 调用 unsafe 函数(包括 FFI)
- 读写可变静态变量(
static mut) - 实现 unsafe trait(
unsafe impl) - 访问 union 字段
unsafe 不关闭 borrow checker、类型检查、生命周期检查。仅开放上述 5 项”超级权限”。
FFI(Foreign Function Interface)通过 extern "C" 块声明外部函数。编译器按指定 ABI 生成调用代码(参数寄存器、栈对齐等)。Rust 侧的 #[no_mangle] 防止符号名混淆。
Unsafe 的契约模型:safe Rust 是 unsafe Rust 的安全封装。库作者负责在 unsafe 层确保所有安全不变量(invariant),用户无需关心实现细节。典型例子:Vec<T> 内部 unsafe 操作裸指针和分配器,对外暴露安全 API。
指针运算通过 ptr::add(), ptr::offset() 等方法,区别于 C 的 p++。读写通过 ptr::read() / ptr::write(),不调用 drop 或 copy 构造。
语法
// 裸指针解引用
let mut x = 5;
let raw = &mut x as *mut i32;
unsafe { *raw = 10; }
// FFI
extern "C" {
fn abs(input: i32) -> i32;
}
unsafe { println!("{}", abs(-3)); }
// 导出给 C 使用
#[no_mangle]
pub extern "C" fn rust_fn(x: i32) -> i32 { x + 1 }
// Union
union MyUnion {
i: i32,
f: f32,
}
let u = MyUnion { i: 42 };
unsafe { println!("{}", u.i); }
// 全局可变状态
static mut COUNTER: u32 = 0;
unsafe { COUNTER += 1; }原始指针操作
let mut v = vec![1, 2, 3];
let p = v.as_mut_ptr();
unsafe {
ptr::write(p.add(0), 10);
ptr::write(p.add(1), 20);
let val = ptr::read(p.add(1));
}unsafe trait
unsafe trait UnsafeTrait { }
unsafe impl UnsafeTrait for i32 { }
// impl 者承诺满足契约实践
力扣问题
对于算法竞赛,unsafe 通常不必要。注重标准安全 API 即可。
AI 自检
unsafe块中 borrow checker 仍然生效吗?举例证明。extern "C"和extern "Rust"的 ABI 区别?调用约定在 x86_64 上的具体差异是什么?