Consider this:
std::string foo();
void bar() {
const std::string& r1 = foo();
static const std::string& r2 = foo();
}
I know that the lifetime of the string resulting from the first call to foo()
will be extended to the lifetime of r1
.
What about the temporary bound to r2
, though? Will it live until the end of the scope or will it still be there when bar()
is re-entered?
Note: I am not interested whether a particular compiler does so. (I am interested in the one we use, and I can test easily with that.) I want to know what the standard has to say on this.
The temporary is extended to the lifetime of the reference.
[C++14: 12.2/5]:
The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
- A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
- A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
- The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer. [ Example:
struct S { int mi; const std::pair<int,int>& mp; }; S a { 1, {2,3} }; S* p = new S{ 1, {2,3} }; // Creates dangling reference
—end example ] [ Note: This may introduce a dangling reference, and implementations are encouraged to issue a warning in such a case. —end note ]
(In particular, note that none of the bullet points match this scenario.)
So, in this case, it's essentially until the program ends.
We can, of course, test this pretty trivially:
#include <iostream>
struct Tracked
{
Tracked() { std::cout << "ctor\n"; };
Tracked(const Tracked&) { std::cout << "copy\n"; };
~Tracked() { std::cout << "dtor\n"; };
};
void foo()
{
static const Tracked& ref = Tracked();
}
int main()
{
std::cout << "main()\n";
foo();
std::cout << "bye\n";
}
Result:
main()
ctor
bye
dtor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With