17

The code below compiles and runs just fine. Just when I thought I'm starting to get a decent grasp on rvalue reference and std::forward - this very simple code uncovers there is something very fundamental about rvalue I don't understand. Please clarify.

#include <iostream>
#include <iomanip>
using namespace std;

void fn( int&& n )
{
    cout << "n=" << n << endl;
    n = 43;
    cout << "n=" << n << endl;
}


int main( )
{
    fn( 42 );
}

I compile it with g++ 4.7 with the following command line:
g++ --std=c++11 test.cpp

The output is:
n=42
n=43

My main issue is where does the compiler store the 'n' within the function fn?

Naveen
  • 74,600
  • 47
  • 176
  • 233
Uri London
  • 10,631
  • 5
  • 51
  • 81

2 Answers2

7

I can tell some details of what happens here on the low level.

  1. A temporary variable of type int is created on the stack of main. It's assigned with value 42.

  2. The address of the temporary is passed to fn.

  3. fn writes 43 by that address, changing the value of the temporary.

  4. The function exits, the temporary dies at the end of the full expression involving the call.

Andriy
  • 8,486
  • 3
  • 27
  • 51
  • 2
    "The function exits, the temporary dies." -- in some sense that's two separate steps. It happens in this example that the function call is the outermost part of the full-expression containing the temporary, but if the expression were something like `fn(42), fn(43), fn(44);` then nominally the three temporaries would not be destroyed until all three function calls finished. – Steve Jessop Oct 16 '12 at 10:14
2

Takes its address, i.e. &n and you will see its pointer value.

You can stick a local variable into your function and also in main and take their addresses too and see where that is, but relying on any comparison between them would be undefined behaviour.

That the int is not const is correct, your function acquires it. In the same way you can initialise a class with a collection using an r-value reference and then class can modify it later, i.e. it doesn't have to be a const member. However there will be no copy.

The object that is "moved" will, by the standard, be in a stable, usable state, but the actual value it holds is undefined.

CashCow
  • 30,981
  • 5
  • 61
  • 92