【问题标题】:Why does a const disappear during linking when static doesn't?为什么在静态链接过程中 const 没有消失?
【发布时间】:2021-03-10 05:31:28
【问题描述】:

我的静态库 crate 中有这样的函数:

use super::*;

static BLANK_VEC: [u8; 16] = [0_u8; 16];
pub fn pad(name: &'static str) -> String {
    let mut res = String::from(name);
    res.push_str(&String::from_utf8_lossy(&BLANK_VEC[name.len()..]));
    res
}

当我将它链接到 C 代码时,它按预期工作,但如果我链接下面的代码(唯一的区别是 const 而不是 static)标签 BLANK_VEC 不会出现在 ELF 文件中.它可以编译并运行,直到它得到一个 HardFault。

use super::*;

const BLANK_VEC: [u8; 16] = [0_u8; 16];
pub fn pad(name: &'static str) -> String {
    let mut res = String::from(name);
    res.push_str(&String::from_utf8_lossy(&BLANK_VEC[name.len()..]));
    res
}

这是 Rust 方面的错误吗?我这么认为是因为const 变量不知何故超出了范围。我可以引用它并编译它。内存安全保障在哪里?为什么我不必使用 unsafe 块来执行此操作?

如果这取决于我的链接器:我使用arm-gcc-none-eabi

编辑:我理解为什么会发生这种情况,但 Rust 不应该确保用户使用不会消失的变量吗?

【问题讨论】:

  • 另见stackoverflow.com/a/52753798/1021920,尤其是“发生次数”下方的文字
  • stackoverflow.com/questions/52751597/…stackoverflow.com/questions/45550387/… 尤其是 const and static do not mean the same things in Rust and C 部分
  • 既然问题已经发布了一个很好的答案,我认为最好把这个问题留作为什么符号BLANK_VEC没有出现在链接器输出中 (这就是 Masklinn 的回答)并针对 为什么我在运行此代码时出现错误 提出一个新问题(您还应该为此提供更多上下文,例如您链接到的 C 代码)。在答案已经发布后更改问题是不受欢迎的;提出一个新问题很好,也值得鼓励。
  • 好的会这样做

标签: c memory-management rust linker


【解决方案1】:

这不是 rust 中的错误:const 定义了一个在每个使用站点复制的常量(因此在运行时不存在)。

static 定义了一个全局变量(它可能是常量,也可能不是常量),因此它存在于最终程序中,它是内存中实际的单个位置。

【讨论】:

  • 好的,但是为什么它会编译。这不是不安全吗。我认为至少应该对此提出警告。你是对的,这不是一个错误,但这看起来不像是 Rust 会做的事情。
  • 链接本质上是不安全的;见issue #28179。但是,我认为这里没有任何不安全之处。为什么你认为这个特定的代码是不安全的?
  • 顺便假设在输出中标记了 private 静态变量似乎很乐观。我认为 rustc 有权不嵌入它,因为它在输出中不可见。
  • @selmanözlyn 在任何地方,Rust 都允许您使用名称,它是在范围内的定义。 BLANK_VEC 没有链接,但这与符号BLANK_VEC 的使用有关,而不是它后面的值,它始终有效。这就像 C 中的 #define 或 C++ 中的 inline constexpr,它们也没有链接。我不知道 HardFault 是什么意思,但如果它是运行时内存错误,可能意味着您在某处有一个不正确的 unsafe,或者您的 C 代码行为不端。 Rust 没有理由警告您在此代码中使用 BLANK_VEC;没有办法用它来制造不安全。
  • @selmanözlyn 您不会在几天后更改问题,而是创建新问题,或者在更适合讨论事物的网站上提问(所以 真的 不是,因为评论系统很垃圾)。
猜你喜欢
  • 2015-12-19
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-03
  • 2015-01-02
相关资源
最近更新 更多