Reputation: 5665
In C++11/14 we have: Return value optimization, move semantics, some classes like unique_ptr which don't have copy ctor
Q1: What is a correct behavior of the code snippet below when DECLARE_COPY_CTOR is equal to 1 or to zero ?
Q2: Console application built with MSVC 2013 for code snippet below in DEBUG build for Win32 gives in console: A(), A(A&&), ~A(), ~A(). So looks like lvalue referencce "a" was used to bind to "A&&". Is it legal? I thought that only temporary objects can be a candidate for move.
Q3: In RELEASE build compiler choose to use Rvo (so output was: A(), ~A())
Is compiler free to choose is "a" in function scope is a canditate for move?
#include <stdio.h>
#include <iostream>
#include <memory>
#define DECLARE_COPY_CTOR 0
class A
{
public:
A() {puts("A()");}
~A() { puts("~A()"); }
#if DECLARE_COPY_CTOR
A(A&) { puts("A(A&)"); }
#endif
A(A&&) { puts("A(A&&)"); }
A& operator = (A&) { puts("A& operator = (A&)"); return *this; }
};
A F()
{
A a; // here a is lvalue
return a; // here a is still lvalue
}
int main()
{
auto i = F();
return 0;
}
Upvotes: 0
Views: 33
Reputation: 238311
Q1. What is a correct behavior of the code snippet below when DECLARE_COPY_CTOR is equal to 1 or to zero ?
DECLARE_COPY_CTOR
has no effect on the behaviour. Copy constructor is not invoked in the program.
Q2. So looks like lvalue referencce "a"
a
is an lvalue, but it isn't an lvalue reference.
Q2. Is it legal?
Yes, it is legal to return a non-copyable local lvalue. It will be moved.
Q3. Is compiler free to choose is "a" in function scope is a canditate for move?
If the type of returned local variable is movable, then it must be moved rather than copied. NRVO applies to this case, so the compiler is free to elide the move - just like it was free to elide the copy prior to c++11.
Upvotes: 2