Search code examples
c++rvalue-reference

C++ pass by reference tricky situation


I'm trying to figure what happens to an "rvalue",temporary object, after the variable used to refer this object deleted from stack.

Code example:

#include<iostream>
using namespace std;

class Base
{
  private:
  int &ref;
  public:
  Base(int &passed):ref(passed)
  {
    cout << "Value is " << ref << endl;
  }
  int getvalue(){
    return ref;
  }
};

int main()
{
  Base *myobject;
    {
    int ref=10;
    myobject = new Base (ref);
    ref++;
    }                           //ref delete from stack. 
  cout << myobject->getvalue() << endl;
  return 0;
}

I expected the second output(second cout) to give me some random garbage because ref deleted but instead I got the value of the current state of ref, I wander what happened after the ref got deleted is it pure luck? or myobject.ref stored the value of the ref he construct with?

Edit: adding a visualizer to support my point that in the end myobject.ref pointing nowhere C++ visualizer


Solution

  • From Reference declaration documentation

    it is possible to create a program where the lifetime of the referred-to object ends, but the reference remains accessible (dangling). Accessing such a reference is undefined behavior.

    In your program the referred-to object ref ends at } after ref++. This means that the ref data member is now a dangling reference. And according to the above quoted statement, accessing that reference(which you do when you call getValue) is undefiend behavior.

    Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.

    So the output that you're seeing(maybe seeing) is a result of undefined behavior. And as i said don't rely on the output of a program that has UB. For example, the output of the same program is different here and here.

    So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.


    1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.