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

时间:2017-02-20 17:45:52

标签: 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
}

当我使用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或其中一个标志不同?)

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

1 个答案:

答案 0 :(得分:5)

在Rust 1.13.0之前,实际上始终为#[inline]函数生成本机代码。未在包中使用的changed#[inline]函数中的Rust 1.13.0不会编译为本机代码。此更改的primary motivation是包含许多内联函数的库,如果它们根本没有转换为本机代码,则编译速度要快得多。

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

  

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

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