直接回答:soundness 指:仅用 safe API 的组合,无论怎么调用(含恶意构造),都不可能产生未定义行为。一个 safe 函数只要存在某种调用方式触发 UB,这个抽象就是 unsound 的——即使那种用法“明显是误用”。责任边界:库作者对公开 safe API 的全部调用组合负责;使用者的责任从 unsafe 关键字落笔那一刻开始。
展开解析:边界细节值得掰开:库内部可以用 unsafe,但必须证明“safe 输入 ⇒ 无 UB”——证明义务在作者,工具是 Miri、文档化的不变量、审阅;使用者调 unsafe fn 时承担了文档契约(对齐、生命周期、独占性),违反即 UB 且锅在自己。模糊地带一:panicking 与逻辑错误不算 unsound——返回错误结果、死锁、泄漏(mem::forget 是 safe 的)都不破坏内存安全,Leakpocalypse 事件确立了“泄漏安全”这一底线,直接后果是不能依赖析构函数一定执行来做安全保证(take/replace 设计的由来)。模糊地带二:private API 被 safe 代码错误使用导致 UB 也算库的责任——内部不变量必须对模块内所有 safe 路径成立。模糊地带三:环境假设——依赖全局状态(环境变量、当前目录)的安全函数在并发下是否 unsound,社区按“libc 保证什么”划线(setenv 因此趋向 unsafe)。对库作者的实操建议:unsafe 最小化并集中、不变量写进注释、公开 API 走一遍“恶意使用者”思想实验、CI 挂 Miri。soundness bug 在 crates.io 上按安全漏洞处理(RUSTSEC),可见其严肃性。
追问方向:为什么 mem::forget 必须是 safe 的?unsound 与 logic bug 的分界为什么重要?
(约 490 字)