Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the lifetime of a reference extended?

I'd like to pass a reference into a function. This code does not work, as I'd expect:

struct A {
};

void foo(A& a) {
    // do something with a
}

int main(int, char**) {
    foo(A());
}

I get the compile error

invalid initialization of non-const reference of type A& from an rvalue of type A

But when I just add the method A& ref() to A like below and call it before passing it along, it seems I can use a. When debugging, the A object is destroyed after foo() is called:

struct A {
    A& ref() {
        return *this;
    }
};

void foo(A& a) {
    // do something with a
}

int main(int, char**) {
    foo(A().ref());
}

Is this valid code according to the standard? Does calling ref() magically extend the lifetime of the object until foo() returns?

like image 554
martinus Avatar asked Feb 24 '17 12:02

martinus


People also ask

What happens when a reference goes out of scope?

The reference disappears, the object continues to live. P.S. You are using the term scope incorrectly. Scope is the visibility region for an identifier. Scope by itself has nothing to do with object lifetime.

What is the life time of a local object?

The lifetime of a variable is the time during which the variable stays in memory and is therefore accessible during program execution. The variables that are local to a method are created the moment the method is activated (exactly as formal parameters) and are destroyed when the activation of the method terminates.

What is a lifetime in c++?

C/C++ use lexical scoping. The lifetime of a variable or object is the time period in which the variable/object has valid memory. Lifetime is also called "allocation method" or "storage duration."

What is the lifetime of local object in C Plus Plus?

The lifetime of an object begins when its initialization is complete, and ends when its storage is released. Dynamic storage duration starts when the storage created by (new Type) is initialized, and ends when the object goes out of scope or is deleted by “delete pointer”.


1 Answers

Your code is perfectly valid.

In this line

foo(A().ref());

The instance of a temporary A lives until the end of the statement (;).

That's why it's safe to pass A& returned from ref() to foo (as long as foo doesn't store it).

ref() by itself does not extend any lifetime, but it helps by returning an lvalue reference.

What happens in the case of foo(A()); ? Here the temporary is passed as an rvalue. And in C++ an rvalue does not bind to non-const lvalue references (even in C++11, an rvalue reference does not bind to non-const lvalue references).

From this Visual C++ blog article about rvalue references:

... C++ doesn't want you to accidentally modify temporaries, but directly calling a non-const member function on a modifiable rvalue is explicit, so it's allowed ...

like image 182
rustyx Avatar answered Oct 14 '22 22:10

rustyx