如果我们有一个已经在堆栈上分配的值,那么装箱会将它复制到堆中,然后转移所有权(这就是它在.NET中的工作方式,除了两个副本都能保持活动状态)?或者编译器是否“足够”以便从一开始就直接在堆上分配它?
struct Foo {
x: i32,
}
fn main() {
// a is allocated on stack?
let a = Foo { x: 1 };
// if a is not used, it will be optimized out
println!("{}", a.x);
// what happens here? will the stack allocated structure
// be moved to heap? or was it originally allocated on heap?
let b = Box::new(a);
}
我不是汇编程序的专家,但看起来它实际上是在堆栈上分配然后移动:http://pastebin.com/8PzsgTJ1 . 但我需要一个确实知道发生了什么的人的确认 .
2 回答
如你所描述的那样,这种优化会发生,这很奇怪 . 例如,在此代码中:
&a
和&b
将是平等的,这将是令人惊讶的 . 但是,如果你做类似的事情,但不要观察a
:你可以see via the LLVM IR这个案例是优化的:
类似地,您可以在堆栈上返回结构,然后将其打包,仍然会just be the one allocation:
正如官方Rust文档here中所述,
Box<T>::new(x: T)
在堆上分配内存,然后将参数移动到该内存中 . 在let b = Box::new(a)
之后访问a
是编译时错误 .