不安全的 extern

概述

  • extern 现在必须使用 unsafe 关键字标记。

详情

Rust 1.82 版本在所有版本中添加了使用 unsafe 关键字标记 extern 的能力。1 添加 unsafe 关键字有助于强调 extern 块的作者有责任确保签名的正确性。如果签名不正确,则可能导致未定义行为。

不安全的 extern 块的语法如下所示

#![allow(unused)]
fn main() {
unsafe extern "C" {
    // sqrt (from libm) may be called with any `f64`
    pub safe fn sqrt(x: f64) -> f64;

    // strlen (from libc) requires a valid pointer,
    // so we mark it as being an unsafe fn
    pub unsafe fn strlen(p: *const std::ffi::c_char) -> usize;

    // this function doesn't say safe or unsafe, so it defaults to unsafe
    pub fn free(p: *mut core::ffi::c_void);

    pub safe static IMPORTANT_BYTES: [u8; 256];
}
}

除了能够将 extern 块标记为 unsafe 之外,您还可以指定 extern 块中的单个项是 safe 还是 unsafe。标记为 safe 的项可以在没有 unsafe 块的情况下使用。

从 2024 版本开始,现在需要在 extern 块上包含 unsafe 关键字。这旨在非常清楚地表明 extern 定义必须遵守安全要求。

1

有关原始提案,请参阅 RFC 3484

迁移

missing_unsafe_on_extern lint 可以更新 extern 块以添加 unsafe 关键字。该 lint 是 rust-2024-compatibility lint 组的一部分,该组包含在自动版本迁移中。为了迁移您的代码以兼容 Rust 2024 版本,请运行

cargo fix --edition

请注意,此自动迁移将无法验证 extern 块中的签名是否正确。手动审查其定义仍然是您的责任。

或者,您可以手动启用该 lint 以查找需要更新 unsafe 块的位置。

#![allow(unused)]
fn main() {
// Add this to the root of your crate to do a manual migration.
#![warn(missing_unsafe_on_extern)]
}