0

UPDATE: To be even more explicit, and avoid misunderstandings: What I am asking is, in case of returning a named value, does the C++17 standard GUARANTEE that the move constructor will be invoked if I do std::move on the return value?. I understand that if not using std::move, compilers are allowed, but not required, to entirely elide copying and move constructors and just construct the return value in the calling function directly. That is not what I want to do in my example, I want guarantees.

Consider

class A; // Class with heap-allocated memory and 'sane' move constructor/move assignment.

A a_factory(/* some args to construct an A object */) 
{
  // Code to process args to be able to build an A object.
  A a(// args); // A named instance of A, so would require non-guaranteed NRVO.
  return std::move(a);
}

void foo()
{
  A result = a_factory();
}

In this scenario, does the C++ standard guarantee that no copying will take place when constructing the result object, i.e. do we have guaranteed move construction?

I do understand the drawbacks of explicit std::move on a return value, e.g. in cases where class A is unmovable, we cannot do late materialization of temporaries and get 0 copy even without a move constructor in the class. But my specific question is this - I come from a hard real-time background and the current status of NRVO not being guaranteed by the standard is less than ideal. I do know the 2 specific cases where C++17 made (non-named) RVO mandatory, but this is not my question.

Erik Alapää
  • 2,335
  • 10
  • 23
  • What makes you think the compiler won't move if you don't use `std::move` here? You are returning a local variable by value. – super Apr 04 '20 at 08:46
  • @super: I never said the compiler won't move. I said I want guarantees on no copying. – Erik Alapää Apr 04 '20 at 08:47
  • If the type can't be moved, you can never get that guarantee. If the type can be moved, `std::move` effectively does nothing but harm. – super Apr 04 '20 at 08:48
  • @super: Read my specific scenario. I explicity said A has sane move construction and move assignment defined, and that I want a guarantee from the standard that when using std::move, I get no copy. So yes, std::move may be beneficial if the language rules imply such a guarantee, improving on NRVO, which is too weak for my needs. – Erik Alapää Apr 04 '20 at 08:54
  • And I'm saying that returning without `std::move` will already make use of the move-constructor if one is available (in case of no NRVO). This has been the case since back in `c++11`. – super Apr 04 '20 at 09:00
  • See [this question](https://stackoverflow.com/questions/17473753/c11-return-value-optimization-or-move) for example. – super Apr 04 '20 at 09:07
  • Again, as I said, when doing NRVO witohut std::move, C++17 does NOT guarantee copy elision. My question is if std::move will enable the compiler to always move, guaranteed. – Erik Alapää Apr 04 '20 at 09:38
  • 1
    I don't really see what's not clear. Did you read the link I posted? It is guaranteed to move WITHOUT using `std::move`. The only effect `std::move` has here is that it will guarantee no copy elision even if it would be possible. – super Apr 04 '20 at 09:47
  • @super, ok then I see what you mean. It is this very guarantee I was fishing for, i.e., C++17 does not guarantee NRVO, but it does guarantee move? This has not been clear in the books and other sources I have studied, and it is a very important and generic case. – Erik Alapää Apr 04 '20 at 09:51
  • I don't have a quote from the standard but you can see the section on automatic move from local variables and parameters [here](https://en.cppreference.com/w/cpp/language/return). – super Apr 04 '20 at 09:55

0 Answers0