I've been away from C++ for a while and just recently picked it back up again. Most of what I know about how C++ works comes from a single course. I used to think that once a function returns, all non-dynamically allocated objects go away, and their destructors are called. However, I've realized that's not completely true.
For example, if I write a function like this:
```cpp
A test() {
A a; // Assume A's constructor dynamically allocates memory
return a;
}
```
And then call it like this: `A a = test();`, the memory allocated is still there. But if I just call `test();` alone, the destructor will be invoked. I've learned that this behavior is due to move semantics and some optimizations the compiler can do, which is great, but it also confuses me because it goes against my prior understanding of function mechanics in C++. Is this confusion common?
5 Answers
You should check out Return Value Optimization (RVO) and Named Return Value Optimization (NRVO). There are some nuances to it that can clear up your confusion, especially regarding how the compiler can avoid unnecessary copying of objects.
In your example, yes, a copy of `a` will be returned. However, if you had a function like `A& test() { A a; return a; }`, that would lead to issues, since you’d be returning a reference to a local variable that's destroyed. In C++, it’s on the programmer to know how these behaviors work, unlike languages with garbage collection.
After C++17, no copy happens in the example you provided. But just to clarify, returning a reference to a destroyed object can cause crashes. Most compilers will warn against that.
This seems like a case of pass by value, right? The `A` outside should be a separate copy from the one inside the function. But I might be a bit rusty on my C/C++ knowledge.
Honestly, I don't find it counterintuitive. Normally, you'd expect a function to return a copy, but the compiler is smart enough to optimize that in most situations. So, I think your understanding isn’t as off as you think!
You're correct. The C++ standard allows for copy elision here.