不安全属性
概述
- 以下属性现在必须标记为
unsafe
详情
Rust 1.82 在所有版本中添加了将某些属性标记为 unsafe
的能力,以表明它们具有必须遵守的健全性要求。1 不安全属性的语法如下所示
#![allow(unused)] fn main() { // SAFETY: there is no other global function of this name #[unsafe(no_mangle)] pub fn example() {} }
用 unsafe
标记属性强调了存在必须遵守的安全要求,而编译器自身无法验证这些要求。
从 2024 版本开始,现在要求将这些属性标记为 unsafe
。以下部分描述了这些属性的安全要求。
1
请参阅 RFC 3325 以了解原始提案。
安全要求
no_mangle
、export_name
和 link_section
属性会影响项目的符号名称和链接行为。 必须小心谨慎,以确保这些属性被正确使用。
由于所有链接库中的符号集合是一个全局命名空间,因此如果库之间存在符号名称冲突,则可能会出现问题。 通常,这对于正常定义的函数来说不是问题,因为 符号修饰 有助于确保符号名称的唯一性。 然而,像 export_name
这样的属性可能会破坏这种唯一性假设。
例如,在之前的版本中,尽管仅包含安全代码,但以下代码在大多数类 Unix 平台上都会崩溃
fn main() { println!("Hello, world!"); } #[export_name = "malloc"] fn foo() -> usize { 1 }
在 2024 版本中,现在要求将这些属性标记为 unsafe,以强调必须确保符号被正确定义
#![allow(unused)] fn main() { // SAFETY: There should only be a single definition of the loop symbol. #[unsafe(export_name="loop")] fn arduino_loop() { // ... } }
迁移
unsafe_attr_outside_unsafe
lint 可以更新这些属性以使用 unsafe(...)
格式。 该 lint 是 rust-2024-compatibility
lint 组的一部分,该组包含在自动版本迁移中。 为了迁移您的代码以兼容 Rust 2024 版本,请运行
cargo fix --edition
请注意,此自动迁移将无法验证这些属性是否被正确使用。 仍然需要您手动审查它们的使用情况。
或者,您可以手动启用该 lint 以查找需要更新这些属性的位置。
#![allow(unused)] fn main() { // Add this to the root of your crate to do a manual migration. #![warn(unsafe_attr_outside_unsafe)] }