返回位置的值是否总是在父堆栈帧或接收框中分配? [英] Do values in return position always get allocated in the parents stack frame or receiving Box?

查看:36
本文介绍了返回位置的值是否总是在父堆栈帧或接收框中分配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解从方法返回时结构的行为方式.Rust Book"的 nightlies 部分有一个部分说如果你使用语法......

I was trying to understand how structs behave when returned from methods. There is a section in the nightlies section of the "Rust Book" that said if you used the syntax...

let x = box i_return_a_struct();

.. 不会有副本,因此不需要返回指针.但是当我开始使用它时,似乎不需要 box ,除非您需要该值存在于堆中.

.. that there wouldn't be a copy, therefore there is no need to return a pointer. But when I started playing with it, it appears that the box is not needed, unless you need the value to exist on the heap.

#[derive(Debug)]
struct Dummy {
    data: i64,
}

impl Drop for Dummy {
    fn drop(&mut self) {
        println!("{:?} is going out of scope", self as *const Dummy);
    }
}

fn make_dummy(i: i64) -> Dummy {
    Dummy { data: i }
}

fn main() {
    {
        let i = 15i32;
        println!("{:?} is a variable on the stack frame", &i as *const i32);

        let dummy1 = make_dummy(1);
        println!("{:?} was returned and is being used", &dummy1 as *const Dummy);
        let dummy2 = make_dummy(2);
        println!("{:?} was returned and is being used", &dummy2 as *const Dummy);

        let dummy3 = Box::new(make_dummy(3));
        println!("{:?} box was returned and is being used", &(*dummy3) as *const Dummy);
        let dummy4 = Box::new(make_dummy(4));
        println!("{:?} box was returned and is being used", &(*dummy4) as *const Dummy);
    }
    println!("Leaving main");
}

输出:

0x23fb94 is a variable on the stack frame
0x23faf8 was returned and is being used
0x23fa50 was returned and is being used
0x2825030 box was returned and is being used
0x2825040 box was returned and is being used
0x2825040 is going out of scope
0x2825030 is going out of scope
0x23fa50 is going out of scope
0x23faf8 is going out of scope
Leaving main

返回位置的值/结构是否总是在父堆栈帧或接收框中分配?

Do values/structs in return position always get allocated in the parents stack frame or receiving box?

PS - 文档中是否有关于一般何时会发生复制省略的任何指导?

PS - is there any guidance in the docs for as to when copy elision will occur in general?

除了公认的解决方案,以下 Q+A 很有启发性:什么是移动语义 为我澄清了很多问题.

Beyond the accepted solution, the following Q+A was enlightening: What are move semantics exactly? Clarified many points for me.

推荐答案

也许我不清楚你不明白什么.我想你明白,但也许你还不知道 :D

Maybe it's not clear to me what you don't understand. I think you understand, but maybe you don't know yet :D

通常,函数的返回值(例如make_dummy)被压入堆栈.现在假设您想要堆上的对象.使用新的 box 语法,如果您想要堆上的对象,编译器可以做一些优化.

Normally, the return value of a function (make_dummy for example) is pushed on the stack. Now suppose you want the object on the heap instead. With the new box syntax the compiler can do some optimization if you want the object on the heap.

现在让我们以书中的例子为例.

Now let's take the example from the book.

let y: Box<Dummy> = box make_dummy(some_dummy);

您可能认为在上面的示例中会发生以下情况:

You may think that in the above example the following happens:

  1. make_dummy 的返回值被写入堆栈(正常)
  2. 一个盒子被分配来包含一个 Dummy 对象
  3. 栈上的Dummy值被box对象复制到内存指针中.
  1. the return value from make_dummy is written into the stack (as normally)
  2. a box is allocated to contain a Dummy object
  3. the Dummy value on the stack is copied in the memory pointer by the box object.

使用旧的 Box::new 机制,这正是会发生的情况.相反,多亏了实验性的框语法,这才发生了:

With the old Box::new mechanism this is exactly what would happen. Instead, thanks to the experimental box syntax, this happened:

  1. 分配了一个盒子
  2. 指向那个盒子的指针以某种方式传递给 make_dummy 函数(带有一些编译器魔法),因此返回值被直接写入到盒子内存中[没有涉及堆栈的额外副本]
  1. A box is allocated
  2. The pointer to that box is passed in some way to the make_dummy function (with some compiler magic), so the return value is written directly to the boxed memory [there's no extra copies involving the stack]

我希望现在更清楚了.

这篇关于返回位置的值是否总是在父堆栈帧或接收框中分配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆