2

Here is a simple struct

pub struct Point {
    x: uint,
    y: uint
}

impl Point {
    pub fn new() -> Point {
            Point{x: 0u, y: 0u}
    }
}

fn main() {
    let p = box Point::new();
}

My understanding of how the constructor function works is as follows. The new() function creates an instance of Point in its local stack and returns it. Data from this instance is shallow copied into the heap memory created by box. The pointer to the heap memory is then assigned to the variable p.

Is my understanding correct? Does two separate memory regions get initialized to create one instance? This seems to be an inefficient way to initialize an instance compared to C++ where we get to directly write to the memory of the instance from the constructor.

RajV
  • 6,860
  • 8
  • 44
  • 62

2 Answers2

9

From a relevant guide:

You may think that this gives us terrible performance: return a value and then immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is smarter than that. There is no copy in this code. main allocates enough room for the box, passes a pointer to that memory into foo as x, and then foo writes the value straight into the Box.

This is important enough that it bears repeating: pointers are not for optimizing returning values from your code. Allow the caller to choose how they want to use your output.

While this talks about boxing the value, I believe the mechanism is general enough, and not specific to boxes.

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
7

Just to expand a bit on @Shepmaster's answer:

Rust (and LLVM) supports RVO, or return value optimization, where if a return value is used in a context like box, Rust is smart enough to generate code that uses some sort of out pointer to avoid the copy by writing the return value directly into its usage site. box is one of the major uses of RVO, but it can be used for other types and situations as well.

reem
  • 7,186
  • 4
  • 20
  • 30