Search code examples
c++visual-c++rvalue-reference

Binding rvalue-reference to a local variable in VC++


I'm using VC++2012 to run the following code:

#include <utility>

struct A
{
    int* m_p;

    A() { m_p = new int; }
    ~A() { delete m_p;  }

    A(const A& otherA)
    {
        m_p = new int;

        // BOOM!
        *m_p = *otherA.m_p;
    }
};

A&& CreateA()
{
    A a;
    return std::move(a);
}

int _tmain(int argc, _TCHAR* argv[])
{
    A a2 = CreateA();
    return 0;
}

During the creation of a2 A's copy ctor is called - and crashes, since the source object created in CreateA() is already destroyed. Is this standard behaviour? Could this be a compiler bug??

Notice that if you change a2's type from 'A' to 'const A&' the crash doesn't occur - which reinforces the suspicion that it is indeed a bug. Can anyone shed some light on this?

Note: I'm fully aware this is not the intended usage for rvalue-refs, and this example is contrived. Just hoping to get a better grasp on the behaviour of this new type.


Solution

  • Look at what happens in your code:

    1. CreateA() is called
    2. inside the function, a local variable of type A is created.
    3. you create a rvalue reference pointing to this local variable
    4. you return this rvalue reference
    5. as you return, the object of type A, which the rvalue reference points to, goes out of scope, and gets destroyed
    6. the reference now points to a destroyed object
    7. you try to initialize a2 as a copy of the object that once existed inside the function call

    And... that doesn't work. The object you're trying to copy is dead and gone. Undefined behavior.

    Don't do that. :)

    In C++, references do not affect the lifetime of the referenced object. There is no "I'm pointing at this object, so you can't destroy it!".

    Never return references to local objects. It doesn't work, so... just don't do it.