James Franco
James Franco

Reputation: 4706

Returning an rvalue - what is wrong with this code?

I came across the following code snippet

std::string&& test()
{
    std::string m="Hello";
    return (std::move(m));
}

int main()
{
     std::string&& m = test();
}

I understand the above code is incorrect and unsafe but I am not sure why. So far this is my understanding of the code. In the function test

  1. a local std::string variable called m is created on the stack.

  2. This string is then returned however instead of a copy being made its contents are moved to the temporary. At this point the function test ends calling the destructor of variable m (whose contents were moved to the temp)

  3. The temporary is now bound to the rvalue reference m. And from what I understand is that a temporary will remain alive until its binding object is alive and in scope .

Could someone please tell me where I might be going wrong ? Why is the code above unsafe ?

Upvotes: 2

Views: 211

Answers (1)

Praetorian
Praetorian

Reputation: 109119

An rvalue reference is still a reference, your code is incorrect for the same reason as the function shown below

std::string& test()
{
    std::string m="Hello";
    return m;
}

In both cases, the function returns a reference to a local variable. std::move doesn't do anything other than cast m to string&&, so there is no temporary created that m in main then binds to. When test exits, the local variable is destroyed, and m is a dangling reference.

To fix your code, change the return type from string&& to string.

std::string test()
{
    std::string m="Hello";
    return m;   // std::move is redundant, string will be moved automatically
}

int main()
{
     std::string&& m = test();
}

Now the m in main can bind to the return value of test, and the lifetime of that is extended to match that of m.

Upvotes: 6

Related Questions