0
#include <iostream>
using namespace std;

class A {
    public:
        int i;
        A(int j) : i(j){ cout << "A::A()" << '\n';}
        ~A(){ cout << "A::~A()" << '\n';}
};

A& fun2() {
        A a1(10);
        A &aref = a1;
        return aref;
}

int main() {
        A &a2 = fun2();
        cout << "a2.i : " << a2.i << '\n';
        a2.i = 20;
        cout << "a2.i : " << a2.i << '\n';
        fun2().i = 30;
        cout << "a2.i : " << a2.i << '\n';
        return 0;
}

Output:

ubuntu@ubuntu-VirtualBox:~/Vaibhav_New$ ./Test8  
A::A()  
A::~A()  
a2.i : 10  
a2.i : 20  
A::A()  
A::~A()  
a2.i : 30  

In fun2(), local object a1 is created and destroyed as function exits. I returned the reference and playing with the object(a2.i).

Q1) Why am I able to do this?

When I call the fun2() again, another object (old local object is already destroyed: destructor is called) is created and destroyed. I modified it (don't know how) as following:

fun2().i = 30;

Q2) Why is this affecting object a2?

Earlier: a2.i : 20
    Now: a2.i : 30

I'm not new to C++ but references are still mystery for me :(

GingerPlusPlus
  • 5,336
  • 1
  • 29
  • 52
NightFurry
  • 358
  • 1
  • 17
  • You're invoking UB by returning the address of a temporary. C++ is not java, it allows you to screw yourself over if you want to. – Ed S. Aug 30 '14 at 20:27
  • See the linked question for the long version; the short version is that you're using memory that no longer belongs to the original object. – Ben Voigt Aug 30 '14 at 20:33
  • You're not "allowed" to do it. You don't get a compile error because this problem is not detectable in the general case (which is a lie). – Lightness Races in Orbit Aug 30 '14 at 20:53
  • @LightnessRacesinOrbit: What's a lie? – Ben Voigt Aug 30 '14 at 21:35
  • @BenVoigt: I don't see why a compiler can't detect, in the general case, that it's about to return a reference to a local. Yet I often hear that it is intractible (hence the UB rather than ill-formity). – Lightness Races in Orbit Aug 31 '14 at 01:12
  • @LightnessRacesinOrbit: There are cases where it is intractable, but that's not a good excuse for diagnosing the majority of cases that could be detected. – Ben Voigt Aug 31 '14 at 01:20
  • @LightnessRacesinOrbit: Simple example: `return vec[0];`, where `vec` is an automatic variable in local scope -- can be detected only by looking into `std::vector::operator[]` and the vector destructor. Put a function defined in a separate compilation unit into the path, and I think you can see the severe difficulty in detecting escaped references at compile time. – Ben Voigt Aug 31 '14 at 01:24
  • @BenVoigt: Oh, yeah, true. – Lightness Races in Orbit Aug 31 '14 at 01:26
  • `s/ (which is a lie)//` – Lightness Races in Orbit Aug 31 '14 at 01:26

0 Answers0