【问题标题】:Why are pub functions marked `#[inline]` not present in the compiled object file?为什么已编译的目标文件中不存在标记为“#[inline]”的 pub 函数?
【发布时间】:2017-02-20 17:45:51
【问题描述】:

我用cargo new a 创建了一个全新的板条箱,并在src/lib.rs 中输入了这个:

pub fn xor(a: i32, b: i32) -> i32 {
    a ^ b
}

#[inline]
pub fn xor_inline(a: i32, b: i32) -> i32 {
    a ^ b
}

当我用cargo build --release 编译时,生成的.rlib 只包含xor 而不是xor_inline

$ gnm -D -C target/release/deps/liba-6a3c2798185fafee.rlib
gnm: __.SYMDEF: File format not recognized

a-6a3c2798185fafee.0.o:
0000000000000000 T a::xor::hf0d97103d53d3286
gnm: rust.metadata.bin: File format not recognized
gnm: a-6a3c2798185fafee.0.bytecode.deflate: File format not recognized

gnm 是通过 Homebrew 在 MacOS 上安装的 GNU nm。)

我有两个问题:

  1. 为什么xor_inline 不在目标文件中?我相信它的来源必须存在于rust.metadata.bin 中,这样才能跨箱内联工作,但是为什么没有从目标文件中导出普通函数?

  2. rustc 中是否有任何标志可以与cargo rustc --release -- ... 一起使用以确保所有#[inline] 函数都存在于目标文件中? (可能是不同的--crate-type-C 下的标志之一?)

(我需要这个,因为我想检查生成的程序集以查找我的 crate 中的函数,而不必删除所有内联属性或将每个内联函数包装在公共非内联函数中。)

【问题讨论】:

  • 相关:根据this answer,rlib 保存了一个标记为内联的函数列表。
  • 为什么没有从目标文件中导出普通函数——我假设这段代码很简单,它总是内联,因此它永远不能被调用,所以没有理由拥有目标代码。 我想检查生成的程序集以了解我的 crate 中的功能 - 一旦内联,该程序集可能看起来或可能根本不像内联和优化的程序集,因此在内联之前检查它甚至可能没有用.

标签: rust


【解决方案1】:

在 Rust 1.13.0 之前,实际上总是为 #[inline] 函数生成原生代码。这个 changed in Rust 1.13.0: #[inline] 在 crate 中没有使用的函数不会被编译为本机代码。此更改的primary motivation 是包含大量它们自己不使用的内联函数的库,如果它们根本不翻译为本机代码,编译起来会快得多。

编译器仍然以中间表示形式发出函数,以便编译器可以在其他 crate 中内联和优化它。

(我需要这个,因为我想检查生成的程序集以查找我的 crate 中的函数,而不必删除所有内联属性或将每个内联函数包装在公共非内联函数中。)

内联函数的全部意义在于允许编译器根据函数的使用方式发出不同的汇编代码。例如,如果某些参数是常量,则接收参数的内联函数可能会使其参数参与constant folding。有时,内联函数调用可以编译到零指令(当 Rust 声称零成本抽象时,他们真的是这个意思!),但你无法从非内联函数调用中看出这一点!因此,我怀疑您想做的事情只会误导您;当你使用内联函数时,你不会看到编译器实际发出的代码。

【讨论】:

  • 有道理,谢谢!我想查看函数的汇编代码的原因是为了确保消除了一些特定的边界检查。我猜如果它们在没有 inline 的情况下被消除,它们也会被 inline 消除(但反过来不一定正确,因为周围的代码可能会帮助编译器消除更多的检查)。有没有比为每个函数创建公共非内联包装器更好的方法来查看函数的独立程序集?
  • @Dogbert: 我猜如果它们在没有内联的情况下被淘汰,它们也会被内联淘汰(但反过来不一定正确,因为周围的代码可能有助于编译器消除更多检查) => 看起来合理的可能并不总是成立;我想知道应用优化的顺序是否不能通过在函数内联时使先前的优化混淆水域来防止边界检查的省略:/
猜你喜欢
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多