为什么编译对象文件中不存在标记为"#[inline]"的pub函数?

Dog*_*ert 4 rust

我创建了一个全新的箱子,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
}
Run Code Online (Sandbox Code Playgroud)

当我编译时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
Run Code Online (Sandbox Code Playgroud)

(gnmnm通过Homebrew在MacOS上安装的GNU .)

我有两个问题:

  1. 为什么xor_inline不在目标文件中?我相信它的源必须存在,rust.metadata.bin以便跨板条内联工作,但为什么普通函数不从目标文件中导出?

  2. 是否有任何标志rustc可用于cargo rustc --release -- ...确保#[inline]目标文件中存在所有功能?(也许是不同的--crate-type或其中一个标志-C?)

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

Fra*_*gné 5

在Rust 1.13.0之前,本机代码实际上总是为#[inline]函数生成.这在Rust 1.13.0中已更改:未在包中使用的函数未编译为本机代码.这种变化的主要动机是包含许多内联函数的库,如果它们根本没有转换为本机代码,那么它们编译的速度要快得多.#[inline]

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

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

内联函数的重点是允许编译器根据函数的使用方式发出不同的汇编代码.例如,如果某些参数是常量,则接收参数的内联函数可能使其参数参与常量折叠.有时,内联函数调用可以编译为零指令(当Rust声称零成本抽象时,它们实际上意味着它!),但你无法从非内联函数调用中得知!因此,我怀疑你想要做的只会误导你; 你不会看到编译器在使用你的内联函数时实际会发出的代码.