How does rvalue backlink work?

Just when I thought that I understand the rvalue link, I ran into this problem. The code is probably overly long, but the idea is pretty simple. There is a function main () and returnRValueRef ().

#include <iostream> #define NV(x) "[" << #x << "=" << (x) << "]" #define log(x) cout << __FILE__ << ":" << __LINE__ << " " << x << endl using namespace std; class AClass { public: int a_; AClass() : a_(0) { log("inside default constructor"); } AClass(int aa) : a_(aa) { log("inside constructor"); } int getInt() const { return a_; } void setInt(int a) { a_ = a; } AClass(AClass const & other) : a_(other.a_) { log("inside copy constructor"); } AClass & operator=(AClass const & rhs) { log("inside assignment operator" << "left value" << NV(a_) << "right value" << NV(rhs.a_)); a_ = rhs.a_; return *this; } AClass & operator=(AClass && rhs) { log("inside assignment operator (rvalue ref)" << "left" << NV(a_) << "right" << NV(rhs.a_)); a_ = rhs.a_; return *this; } }; AClass && returnRValueRef() { AClass a1(4); return move(a1); } int main() { AClass a; a = returnRValueRef(); } 

Ok, I would expect this code to print “built-in default constructor” (for a) first, then “internal constructor” (for a1), and then the destination statement with rhs.a_ = 4. But the output

 testcpp/return_rvalue_ref.cpp:14 inside default constructor testcpp/return_rvalue_ref.cpp:17 inside constructor testcpp/return_rvalue_ref.cpp:39 inside assignment operator (rvalue ref)left[a_=0]right[rhs.a_=0] 

Can someone explain why the last line in the output prints right[rhs.a_=0] instead of right[rhs.a_=4] ? I thought that move () just does an lvalue in an rvalue without changing its contents. But I'm obviously missing something.

Many thanks for your help.: -)

Edit: I think I know what could be. Maybe the destructor for a1 in the function returnRValueRef() is called when it goes out of scope (even if it is included in the rvalue), and after that the memory location for a1 (or the rvalue reference for it) contains undefined material! Not sure if this is what happens, but seems plausible.

+7
source share
1 answer

The rvalue link is still a link. In your case, you are referring to a local variable that has been destroyed. Therefore, undefined behavior has access to members. You want to return an object:

 AClass returnRValueRef() { AClass a1(4); return move(a1); } 

However, the transition happens automatically with a local variable, so you really only need to do this:

 AClass returnRValueRef() { AClass a1(4); return a1; } 
+18
source

All Articles