const数组如何内联?

时间:2015-07-20 03:29:54

标签: rust

关于construst docs state(强调我的):

  

常量适用于程序的整个生命周期。更具体地说,Rust中的常量在内存中没有固定地址。 这是因为它们有效地内联到他们使用的每个地方。由于这个原因,对同一个常量的引用不一定保证引用相同的内存地址。

所以,我想知道const数组是如何“有效内联的”。请参阅以下代码段中的我的评论:

const ARR: [i32; 4] = [10, 20, 30, 40];

fn main() {
    // is this 
    println!("{}", ARR[1]);

    // the same as this?
    println!("{}", [10, 20, 30, 40][1]);

    // or this?
    println!("{}", 20);
}

我感谢任何澄清!

1 个答案:

答案 0 :(得分:6)

这取决于。答案是"以上所有,可能。"让我们稍微修改一下你的例子:

const ARR: [i32; 4] = [10, 20, 30, 40];

#[inline(never)] fn show(v: i32) { println!("{}", v); }

fn main() {
    // is this 
    show(ARR[1]);

    // the same as this?
    show([10, 20, 30, 40][1]);

    // or this?
    show(20);
}

现在,让我们将其编译为LLVM IR,看看main函数的样子:

define internal void @_ZN4main20hf87c9a461739c547ZaaE() unnamed_addr #4 {
entry-block:
  call void @_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
  call void @_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
  call void @_ZN4show20h659b6b1f4f7103c4naaE(i32 20)
  ret void
}

show函数的三次相同调用,每次调用都传递一个常量20。即使启用了优化,这也是不可能的!

就语言保证的内容而言,对show的前两次调用在语义上是相同的。说一个常数是"内联"并不意味着它会自动导致围绕它的所有内容;它只是使值被替换到位。但是,由于Rust的侵略性常量折叠和内联,这三个在实践中是 ,在这个特定情况下