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

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

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)

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.

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

This isn't an easy subject so for what's it worth...

I browsed the standard and in 3.10 I found this

An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its
resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving
rvalue references (8.3.2). [ Example: The result of calling a function whose return type is an rvalue
reference is an xvalue. —end example ]

My interpretation of it is that you in order to not jeopardize the returned value you have to immediately assign it to something persistent. Failure to do so invokes undefined behaviour (didn't find anything explicit to support that though) so when using another compiler, other compiler flags or whatever there will be another result.

Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by
definition, not smart enough to debug it.
- Brian W. Kernighan

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

Originally Posted by S_M_A

My interpretation of it is that you in order to not jeopardize the returned value you have to immediately assign it to something persistent. Failure to do so invokes undefined behaviour

no, it's not undefined behavior per se; it's just that, semantically, xvalues refers to objects from which you can safely steal resources from ( for example, you can turn any lvalue in an xvalue via std::move, which is just a "polite" cast to an rvalue reference ).

that said, the OP code snippet does give undefined behavior, but for the simple reason that he's using a reference (&& or & it would be the same ) to an object that does not exist anymore ( the automatic variable "int a" in foo1() ).

Originally Posted by softwarelover

It seems the value returned by foo1 and received by variable1 dies out after some time - perhaps, a brief period of some milliseconds.

no, this is just a manifestation of undefined behavior.

Originally Posted by softwarelover

Notice also that variable2 never seems to die out, no matter how many times I print it with cout!

in this case the temporary is bound to the reference, as in "int const& variable3 = foo2()". So it's legal and expected behavior.

EDIT: BTW, is it me, or the forum is nearly unusable today ?? it took me ages to edit this damned post ...

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

In my mind we say about the same thing superbonzo, using a reference to an object that doesn't exist anymore give undefined behaviour (maybe that's also what you ment and it's just me not having english as my native language...)

Isn't the thing here though that the returned rvalue reference kind of imply that a move operation has to be executed immediately?

Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by
definition, not smart enough to debug it.
- Brian W. Kernighan

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

Originally Posted by S_M_A

In my mind we say about the same thing

... uhm, I think not: you quoted the definition of xvalue relating it to the return value of the foo1 function; this is quite wrong as the problem here has nothing to do with rvalue references, nor the lifetime of return values. Instead, the problem lies inside the foo1 function, when a reference to an automatic variable is returned.

Originally Posted by S_M_A

Isn't the thing here though that the returned rvalue reference kind of imply that a move operation has to be executed immediately?

what do you mean ? rvalue references are just references, they do not imply any "move operation" per se.

Of course, the semantics of rvalues is such that when they bind to a function argument then that function is expected to possibly steal its resources, treating it as a to-be-moved temporary ( the standard explictly says this; for example, contrary to ordinary references, function implementations are allowed to ignore aliasing checks ). But it's function implementation specific whether or when any move operation actually occurs, and it's class implementation specific how such a move is performed ( note that for non-class types, "move-operations" are just (reference) conversions/initializations ).