1

https://stackoverflow.com/a/8523361/11862989 from this answer this question is came into picture. I feel small thing is wrong in that answer, so I commented out there but no reply from him (guy (190K Reputation) who's answer I am referring) so I am asking here that small part.

1.

.h

struct A
{
    private:
        int &i;
    public:
        A(int);
};

.cpp

A::A(int k1): i(k1)   
{
    std::cout<<&k1<<" "<<k1<<"\n";
    std::cout<<&i<<" "<<i<<"\n";
}

main.cpp

int main()
{
    int x=99;
    std::cout<<&x<<" "<<x<<"\n";
    A a1(x);
}

Output

0x72fe0c 99
0x72fde8 99
0x72fde8 99

2.

.h

struct A
{
    private:
        int &i;  // __change__
    public:
        A(int&);
};

.cpp

A::A(int &k1): i(k1)    // __change__
{
    std::cout<<&k1<<" "<<k1<<"\n";
    std::cout<<&i<<" "<<i<<"\n";
}

main.cpp

int main()
{
    int x=99;
    std::cout<<&x<<" "<<x<<"\n";
    A a1(x);
}

Output

0x72fe0c 99
0x72fe0c 99
0x72fe0c 99

in 2nd code as we are passing reference of x through main and it is collected by k1. and now we passing reference of k1 to i. means now i is referring to k1 and k1 is referring to x. means indirectly i is referring to x am I right ?

in 1st I think here value of variable x is passed through main and it is collected by variable k1 and then reference of k1 is passed to variable i. so in this case variable i is referring to variable k1 but variable k is not referring to variable x am I right ?

that guy(190K Reputation) whose answer I referred at top he used 1st method to do this, I think he is wrong and __2nd__method is right for initializing reference variable of object in class. am I right ?

  • The second means **directly** that `i` is referring to `x`. The initialization is indirect, but `i` ends up being a reference to `x`. In the first, the argument `k1` goes away when the constructor returns. `i` refers to something that no longer exists, and the behavior is undefined. – Pete Becker May 20 '21 at 12:04
  • https://stackoverflow.com/a/68289424/11862989 check this answer too. It will give little bit more insight on this topic. – Abhishek Mane Jul 07 '21 at 16:23

1 Answers1

1

You are right, good catch. Alok's example in the answer you refer to is defective. Your example already shows it, and possible consequences of the undefined behavior of referring to stale references can be seen in this godbolt example. I made A::i public and changed the main function to

int main()
{
  int x = 99;
  cout << &x << " " << x << "\n";

  A a1(x);
  cout << a1.i << " " << "\n";    
  cout << a1.i << " " << "\n";    // not 99 any more!
}

The output in the example is

0x7fff6983d4dc 99
0x7fff6983d4b4 99
0x7fff6983d4b4 99
99 
32767 

The first output creates enough action on the stack to overwrite the address &a1.i, which back then contained the local k1.

A smart compiler could detect this and warn about it; and indeed, clang says warning: binding reference member 'i' to stack allocated parameter 'k1' [-Wdangling-field]. gcc 10.2 does not warn.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • 1
    `&A::i` is a pointer-to-member. Its value is determined solely by the definition of `A`; it's always valid. The pointer you want is `&a1.i`, which is a pointer to the `int` that `a1.i` was initialized to point at. – Pete Becker May 20 '21 at 12:09
  • @Pete thanks for, well, pointing this out. – Peter - Reinstate Monica May 20 '21 at 12:31
  • @Peter-ReinstateMonica are you sure about `undefined behavior` ? I am asking because when we talk about __pointer and address__ not __reference__ okay. So let say ` int a; int *p=&a` and assume `a` is gone out of scope then that case is `dangling ptr` right. I didn't know such thing for __reference`. – Abhishek Mane May 20 '21 at 12:45
  • 1
    @AbhishekMane Yes, of course. See https://en.cppreference.com/w/cpp/language/reference#Dangling_references. As you can see in my example the memory may be re-used; especially writing to it can change arbitrary data (e.g. return addresses) with unforeseeable consequences. – Peter - Reinstate Monica May 20 '21 at 13:47