对于内联的Rust中的const类型是什么意思?

时间:2016-10-20 07:34:10

标签: rust const inline

我是Rust和系统编程的绝对初学者。 Rust中const的文档说明了这一点:

  

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

我在C ++中只遇到过inline functions,但从来没有内联const类型。有人可以提供一个初学者友好的解释,如何工作?

另外,我对no fixed address in memory感到困惑。这是否意味着每次我们使用const类型时,堆栈中的值仅为此表达式分配,并且在表达式执行完毕后,它将被销毁< / em>的

3 个答案:

答案 0 :(得分:6)

  

我只是遇到了C ++中的内联函数,但从未使用内联const类型。

Rust中与const最接近的是C ++中的enum

  

有人可以提供有关其如何运作的初学者友好解释吗?

简单的初学者的解释是:它只是有效,不要担心细节的细节。

  

另外,我对内存中没有固定地址感到困惑。这是否意味着每次我们使用const类型时,堆栈中的值仅为此表达式分配,并且在表达式执行完后,它将被销毁?

是。也许。否。

这正是它在锡上所说的内容:无法保证。这使编译器可以最大限度地自由优化。

好吧,这一切都很好,但......真的发生了什么?

在实践中,有两种情况:

  • 该值足够简单:它甚至不会触及堆栈,而是直接在程序集中进行硬编码。例如,这很可能发生在积分中。
  • 值不是那么简单:它是在只读内存中创建的,并从那里引用/复制。堆栈上的多个副本显然会有不同的地址。

简单是什么意思?这得看情况。对于每个调用站点,编译器可以决定“是否足够简单”,这是接近内联的位置。

  

这是否意味着每次我们使用const类型时,堆栈中的值只为此表达式分配,并且在表达式执行完毕后,它将被销毁?

它不会被破坏。 const变量不能具有实现Drop的类型。当它不再使用时,该值只是忘记。如果曾经占用了堆栈中的内存,有时候这个内存会被覆盖。

答案 1 :(得分:2)

Rust中的

const N: i32 = 5与使用类型安全的C或C ++中的#define N 5类似。

当类型匹配时,您可以将其视为文本替换,即let foo = 32 + N;在您的示例中等同于let foo = 32 + 5;

答案 2 :(得分:1)

const蚂蚁的行为根本不像常规变量;当你定义一个它甚至没有自己的范围用于借用检查目的。

比较以下代码片段生成的MIR:

fn main() {
    const N: i32 = 5;
}

fn main() {
    let n: i32 = 5;
}

你会发现N扩展为更像是函数而不是变量:

const main::N: i32 = {
    let mut _0: i32;                     // return pointer

    bb0: {
        _0 = const 5i32;                 // scope 0 at <anon>:2:20: 2:21
        return;                          // scope 0 at <anon>:2:5: 2:22
    }
}

当在表达式中使用它时,它的值被放置在堆栈中以用于该表达式,并且之后会被忘记。

编辑:至少这是在MIR级别上发生的事情。我不是低级优化的专家,因此必须在LLVM甚至ASM中检查实际结果(是否实际使用堆栈内存)。请注意,这也适用于常规变量。