1

What are the differences between return value optimization and std::move? Do they depend on same internal implementation?

I understand that there are many places where must use std::move.

std::move and RVO both could achieve copy elision.For example, T Func() {return T();} T t=Func();.I think i could not figure out which method the compiler really uses.

I am a novice in C++.I would be grateful for any hint on this question.

sunshilong369
  • 646
  • 1
  • 5
  • 17
  • 2
    `std::move` is just a typecast, it has no relation to RVO – Remy Lebeau May 29 '20 at 05:15
  • @Remy Lebeau `std::move` and RVO both could achieve copy elision.For example, `T Func() {return T();} T t=Func();`.I think i could not figure out which method does the compiler really use. – sunshilong369 May 29 '20 at 05:25
  • https://stackoverflow.com/questions/17473753/c11-return-value-optimization-or-move – QuentinUK May 29 '20 at 05:35
  • https://stackoverflow.com/questions/14856344/when-should-stdmove-be-used-on-a-function-return-value – QuentinUK May 29 '20 at 05:37
  • RVO is a compiler optimization. The compiler is not smart, it is VERY smart and sees that it can reserve the area for return value on stack before reserving memory for the called function that returns value. The returned value is therefore not destroyed when function goes out of scope and stack is decreased. The returned value is still there on stack. move is more of a developer optimization and slower than RVO – Per Ghosh May 29 '20 at 05:37
  • https://stackoverflow.com/questions/4986673/c11-rvalues-and-move-semantics-confusion-return-statement – QuentinUK May 29 '20 at 05:39
  • @ Per Ghosh I see.It makes clear to me how `RVO` is implemented.Then what about `std::move`? – sunshilong369 May 29 '20 at 05:40
  • @PerGhosh Note that since C++17, there is no longer RVO. There is guaranteed temporary deferred materialization, which is a bit different mechanism but basically with the same effect. And, it's not a compiler optimization, since it is prescribed by the Standard. (A difference is, for example, that for RVO you still need accessible copy/move constructor, while in C++17, there is no such need. This code: `std::atomic f() { return std::atomic{false}; } int main() { auto a = f(); }` compiles in C++17, but not in C++11/14.) – Daniel Langr May 29 '20 at 05:46
  • @sunshilong369 move is technique for you as a developer to optimize copy constructors for rvalues (values that is temporary and dies). You can create a copy constructor that know this and therefore "move" allocated data to the new object, not copy data. It's still a function call to the copy constructor. RVO has no call to functions, the objects it just there for use. – Per Ghosh May 29 '20 at 05:50
  • @PerGhosh Thank you very much.What are major differences between `RVO` and `guaranteed temporary deferred materialization`? – sunshilong369 May 29 '20 at 06:00
  • @sunshilong369 Short answer - None. There is a small change that most developers never going to face. RVO do not use copy constructors. But if you create a class and specifically tells that copying isn't allowed. Then this object would generate an error when RVO kicked in but copying wasn't done. – Per Ghosh May 29 '20 at 06:13
  • @sunshilong369 Deferred temporary materialization needs neither copy nor move constructor. This is the case, for instance, of `std::atomic`, which I showed in the example in my previous comment. You cannot apply RVO with `std::atomic`. That's a major difference IMO, though classes without both copy/move constructors are relatively rare. – Daniel Langr May 29 '20 at 06:32
  • Yea, thank you.I have studied your example code and done some test.You make it clear to me.Thank you very much.BTW, what do you mean by "major difference IMO"?I could not find it in any dictionary. – sunshilong369 May 29 '20 at 06:42
  • @sunshilong369 You're welcome. [IMO = _in my opinion_](https://www.urbandictionary.com/define.php?term=IMO) :). – Daniel Langr May 29 '20 at 06:56
  • @Daniel Langr This code: `std::atomic f() { return std::atomic{false}; } int main() { auto a; a = f(); }` could not complie successfully in C++11 and C++17, since copy constructor is still needed in this code.Could i think in this way? – sunshilong369 May 29 '20 at 08:14
  • @sunshilong369 1) `auto a;` — This is not legal in C++. 2) `a = f();` involves an assignment operator, not copy/move constructor. – Daniel Langr May 29 '20 at 08:24

0 Answers0