When are rvalue references to primitive integers short-lived or long-lived?


I have done some experimentation on rvalue references with the TDM-GCC 4.6.1 compiler and made some interesting observations that I cannot explain away with theories. I would like experts out there to help me explain them.

I have a very simple program that does not deal with objects but int primitives and that has defined 2 functions:
foo1 (returning a local variable by rvalue reference) and
foo2 (returning a local variable by value)

#include <iostream>

using namespace std;

int &&foo1();
int foo2();

int main()
{

int&& variable1 = foo1();
//cout << "My name is softwarelover." << endl;
cout << "variable1 is: " << variable1 << endl; // Prints 5.
cout << "variable1 is: " << variable1 << endl; // Prints 0.

int&& variable2 = foo2();
cout << "variable2 is: " << variable2 << endl; // Prints 5.
cout << "variable2 is still: " << variable2 << endl; // Still prints 5!

return 0;
}

int &&foo1() {

int a = 5;
return static_cast<int&&>(a);
}

int foo2() {

int a = 5;
return a;
}

It seems the value returned by foo1 and received by variable1 dies out after some time - perhaps, a brief period of some milliseconds. Notice that I have prevented cout from printing "My name is softwarelover" by commenting it out. If I allow that statement to run, the result is different. Instead of printing 5, 0 it prints 0, 0. Seems like it is because of the time-delay introduced by "cout << "My name is softwarelover." that 5 turns into 0.

Is the above how an rvalue reference is supposed to behave when referring to a primitive integer which a function returned by reference as opposed to return-by-value? By the way, why is it 0, why not garbage?

Notice also that variable2 never seems to die out, no matter how many times I print it with cout! variable2 refers to a primitive integer which a function returned by value, not return-by-reference.

Thanks.
Returning a local variable by reference is undefined behavior, regardless of its value category or type.

When you return by value and bind the temporary to a reference (const lvalue references and rvalue references can both do this), the life of the temporary is extended to the life of the reference, that's why "variable2 never seems to die out"

You can read about reference initialization here: http://en.cppreference.com/w/cpp/language/reference_initialization
Last edited on
Topic archived. No new replies allowed.