cpp_weekly icon indicating copy to clipboard operation
cpp_weekly copied to clipboard

lifetime of local variable

Open Dharmesh946 opened this issue 1 year ago • 7 comments

Channel

C++ weekly

Topics

Object lifetime Return value This SO thread is a rough sum-up of the issue: https://stackoverflow.com/questions/73481385/how-to-determine-when-local-variables-are-destroyed

What is a function local object lifetime? How does it depend on it being part of the return expression? How does it depend on the returned type (plain value, l/rvalue reference)? How does it depend on the call site (here is a very contrived example : https://godbolt.org/z/dEqoMP3ca where a temporary is returned as rvalue reference, binding it to a plain object leads to dangling reference and UB while binding it to a const& expand the lifetime of the bound objet; NB I designed the foo function to avoid (N)RVO).

I found many related questions on SO but it's always focused on a very special case (as imposed by SO) making it difficult to have the "big picture".

Length

I honestly don't know if the subject can be treated in less than 10 minutes or not

Dharmesh946 avatar Sep 25 '24 20:09 Dharmesh946

https://stackoverflow.com/questions/79377674/order-of-execution-in-c-program : raises also questions about the status and lifetime of function argument.

Dharmesh946 avatar Jan 22 '25 13:01 Dharmesh946

somewhat related: returning a reference to a local temporary: https://stackoverflow.com/questions/79450819/r-value-reference-to-default-argument-temporary-to-hold-the-buffer-for-convertin

the use-case seems ok but the tc_str function can be easily misused by getting a reference on the return value, which will eventually get dangling.

Dharmesh946 avatar Feb 19 '25 10:02 Dharmesh946

I'm doing a much higher level introduction than you asked for, I want people to do their own research and learn on their own here: https://compiler-explorer.com/z/n8bd7hhhh

lefticus avatar Apr 21 '25 21:04 lefticus

Hi and thank for your feedback

I played a bit about the notion of returned value : https://godbolt.org/z/YGeP364Wz It helped me construct a mental model of it as I failed to find a clear definition of it in the standard. I imagine it as a (possible) hidden variable that is initialized with the result of the return expression and is then available at the call site. It can be sometime be skipped elided ((N)RVO), plus other details with respect to movability, assignement vs initialization,... What I couldn't understand is, in case of actual construction of the returned value, is it done by the callee or by the caller? This helps to some extent, to understand, when exactly, the lifetime of a local variable ends.

Dharmesh946 avatar May 20 '25 11:05 Dharmesh946

Space for the returned object is allocated by the caller, but only the callee knows how it should be constructed, so the callee does the construction of the return object into the space provided by the caller. If there is a single unambiguous named value being returned on all branches you'll likely get named return value optimization, and in that case when you take the address of the return value before returning it, you'll see its address is already where it's being returned to. As for who is responsible for destruction, I think the callee destroys the returned object if the function exits via exception, and in all other cases the caller destroys the return object with normal rules about objects going out of scope.

LB-- avatar May 20 '25 14:05 LB--

experimentally, it seems to comply with what you're saying. If RV construction throws, it's in callee: https://godbolt.org/z/Pnv3zzz79

Dharmesh946 avatar May 23 '25 08:05 Dharmesh946

This might be a better test maybe? Though it's still difficult to tell who exactly runs the destructor here: https://godbolt.org/z/xW9PhdMTP Also I don't know why MSVC doesn't print the destructor text, maybe there's a compiler bug here?

LB-- avatar May 23 '25 14:05 LB--

Coming in Ep498

lefticus avatar Jul 08 '25 08:07 lefticus