不安全的函数

概要

详情

随着时间的推移,越来越明显的是,标准库中的某些函数应该被标记为 unsafe。然而,向函数添加 unsafe 可能会成为一个破坏性更改,因为它需要将现有代码放置在 unsafe 代码块中。为了避免破坏性更改,这些函数从 2024 版本开始被标记为 unsafe,而在之前的版本中不强制要求 unsafe

std::env::{set_var, remove_var}

在多线程程序中调用 std::env::set_varstd::env::remove_var 可能是不健全的,因为某些平台上处理进程环境的方式存在安全限制。标准库最初将这些定义为安全函数,但后来确定这是不正确的。

务必确保在任何其他线程可能正在运行时,不要调用这些函数。有关更多详细信息,请参阅函数文档的 Safety 部分。

std::os::unix::process::CommandExt::before_exec

std::os::unix::process::CommandExt::before_exec 函数是一个 unix 特定的函数,它提供了一种在调用 exec 之前运行闭包的方法。此函数在 1.37 版本中已弃用,并被 pre_exec 替换,后者执行相同的操作,但被标记为 unsafe

即使 before_exec 已被弃用,但从 2024 版本开始,它现在被正确地标记为 unsafe。这应该有助于确保任何尚未迁移到 pre_exec 的遗留代码都需要一个 unsafe 代码块。

对于 before_exec 闭包,有非常严格的安全要求需要满足。有关更多详细信息,请参阅 Safety section

迁移

为了使您的代码在 2021 和 2024 版本中都能编译,您需要确保这些函数仅在 unsafe 代码块中调用。

⚠ 注意:重要的是您手动检查对这些函数的调用,并可能重写您的代码以满足这些函数的前提条件。特别是,如果可能存在多个线程正在运行,则不应调用 set_varremove_var。您可能需要选择使用环境以外的其他机制来管理您的用例。

deprecated_safe_2024 lint 将自动修改对这些函数的任何使用,将其包装在 unsafe 代码块中,以便它可以在两个版本上编译。此 lint 是 rust-2024-compatibility lint 组的一部分,该组将在运行 cargo fix --edition 时自动应用。要将您的代码迁移为与 Rust 2024 版本兼容,请运行

cargo fix --edition

例如,这将更改

fn main() {
    std::env::set_var("FOO", "123");
}

fn main() {
    // TODO: Audit that the environment access only happens in single-threaded code.
    unsafe { std::env::set_var("FOO", "123") };
}

请注意,这种自动迁移将无法验证这些函数是否被正确使用。手动审查它们的使用情况仍然是您的责任。

或者,您可以手动启用 lint 以查找调用这些函数的位置

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