Can I effectively return an object by value in Rust?

I want the large object to say that Vec<Vec<MyStruct> initialized by the function. I am currently

 fn initialize(mydata : &mut Vec<Vec<MyStruct>>) { ... } 

when i would like

 fn initialize() -> Vec<Vec<MyStruct>> { ... } 

In C ++ often, so I heard it implements optimization of the return value, if you are lucky and you have a good compiler. Can we turn off copying here and return it basically with a hidden pointer that is passed to the function? And is RVO part of the language or optional optimization?

+6
source share
1 answer

Yes, of course you should write

 fn initialize() -> Vec<Vec<MyStruct>> { ... } 

(BTW, Vec not that big - it's just three integers with a pointer, but still)

Rust has an RVO, and this is advertised in manuals like here . You yourself see it.

 #[inline(never)] fn initialize() -> Vec<i32> { Vec::new() } fn main() { let v = initialize(); } 

If you run this program in the playpen using the "asm" button, among everything else you can see this:

 _ZN10initialize20h5d5903a85c1850a8eaaE: .cfi_startproc movq $1, (%rdi) movq $0, 16(%rdi) movq $0, 8(%rdi) movq %rdi, %rax retq 

Vec::new() was built in, but nevertheless, you can see the idea: the address for a new Vec instance is passed to the function in %rdi , and the function stores the Vec fields directly in this memory, avoiding unnecessary copying through the stack. And here is what it's called:

  leaq (%rsp), %rdi callq _ZN10initialize20h5d5903a85c1850a8eaaE 

You can see that ultimately the Vec instance will be pushed directly on the stack.

+12
source

Source: https://habr.com/ru/post/980690/


All Articles