Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will initializing a const reference argument fom a default argument result in a dangling reference? [duplicate]

Tags:

c++

lifetime

void foo(const std::string& s = "abc") {
    // ...
}

// ...

int main() {
    // ...
    foo();
    // ...
}

Will s in foo be dangling? I think because std::string will be constructed from default value "abc", and then this will be a const reference do died temporary.

Am I right?

like image 283
vladon Avatar asked Oct 29 '18 16:10

vladon


People also ask

Does const reference make a copy?

Not just a copy; it is also a const copy. So you cannot modify it, invoke any non-const members from it, or pass it as a non-const parameter to any function.

What does const reference do?

Passing by const reference allows changes to the original object to be visible inside the function.

Can const reference be modified?

Const Reference to a pointer is a non-modifiable value that's used same as a const pointer. Here we get a compile-time error as it is a const reference to a pointer thus we are not allowed to reassign it.

Can you modify a const reference C++?

But const (int&) is a reference int& that is const , meaning that the reference itself cannot be modified.


3 Answers

s will not dangle in foo, but the temporary will live for the entirety of foo. There are a couple pieces that need to be understood to understand why this happens:

  1. When you declare a default argument on the function, the default argument is inserted at the call site. The code you wrote behaves the same as the following code:

    void foo(const std::string& s) {
        // ...
    }
    
    // ...
    
    int main() {
        // ...
        foo("abc");
        // ...
    }
    

    So the std::string temporary is created at the call site.

  2. When the temporary std::string is bound to the const std::string& s, the temporary is lifetime extended. It will live until the end of the complete expression, i.e. the semicolon at the end of foo("abc");.

Putting this together, we can see that s will not dangle, because it points to a temporary string which will live at least as long as foo will execute.

like image 188
Justin Avatar answered Oct 26 '22 22:10

Justin


The constructor for std::string(const char*) will be used to construct a temporary that will live for the whole lifetime of the function.

So there will be no problems.

like image 26
RedX Avatar answered Oct 26 '22 22:10

RedX


No, the lifetime of the temporary will be extended until the evaluation of the expression containing the call to foo ends. If s scape the function body then it will be a dangling reference.

in standardese [class.temporary]/6.9

A temporary object bound to a reference parameter in a function call (8.2.2) persists until the completion of the full-expression containing the call.

like image 32
Jans Avatar answered Oct 26 '22 21:10

Jans