Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lifetime of temporaries [duplicate]

Tags:

c++

Below code shows lifetime of object created in function create() is extended to the life time of const ref created in main, is this correct in all cases? I mean we can extend the life time of temporary in certain cases by creating a reference to it? Or in this specific case the compiler is misbehaving?

It is compiled with MSVC2005

#include <iostream>

class testClass
{
public:
    testClass()
    {
        std::cout << "in testClass " << ((void*)this) << std::endl;
    }

    ~testClass()
    {
        std::cout << "in ~testClass " << ((void*)this) << std::endl;
    }
};


testClass create()
{
    return testClass();
}


int main()
{
    {
        testClass const& obj = create();

        std::cout << "we got a const reference to obj " << ((void*)&obj) << std::endl;
    }

    return 0;
}

Output

in testClass 0018FF13
we got a const reference to obj 0018FF13
in ~testClass 0018FF13

Of course other may get different addresses...In above case i was expecting destructor for the object created with function create(), will be called before line

std::cout << "we got a const reference to obj " << ((void*)&obj) << std::endl; 

is executed.

like image 770
Saqlain Avatar asked Jan 13 '23 15:01

Saqlain


1 Answers

This is a special case: binding a const reference to a temporary object, stretches its lifetime until that const reference goes out of scope. This is only true for function local const references, e.g. the following will not work:

struct X
{
  int const& i
  X(int const& i_) : i(i_) {}
};

int f();

int main()
{
  X x(f()); 
  int u = x.i; //!
}

During construction of x, the i_ will be bound to the temporary returned by f, as will i, but although it's a const reference, that temporarie's lifetime will not be stretched to that of i, i.e. the rule does apply here.

See this GOTW article

Update: as is mentioned in the article and in the comments, the const is vital. The C++ standard allows binding of temporaries only to const lvalue references and rvalue references, so int& i = f(); is not allowed. However, MSVC has an extension that allows this, and as with other references, the lifetime of the temporary is extended until the reference goes out of scope. I would not recommend to exploit that extension, as it makes the code nonportable. In fact, I would be careful binding temporaries to references, since this feature is not well known and your colleagues might be baffled seeing it work, which means the code will lack readability.

like image 161
Arne Mertz Avatar answered Jan 22 '23 07:01

Arne Mertz