I\'ve always assumed that an object begins and ends its lifetime in the same memory location, but I\'ve recently come across a scenario where I need to be sure. Specifically
As mentioned by Nathan Oliver, the standard states that:
[...] An object occupies a region of storage in its period of construction ([class.cdtor]), throughout its lifetime, and in its period of destruction ([class.cdtor]).
Compilers respect this, and there are objects (similar to the one you describe) for which it must hold true. Consider std::mutex. A mutex cannot be copied or moved, and the reason for this is that it must remain at the same location in memory for the duration of it's lifetime in order to work.
Copy/move elision works by creating the object where it needs to go. It's that simple.
We can see this behavior for ourselves:
#include
struct Foo {
Foo() {
std::cout << "I am at " << (void*)this << '\n';
}
// Delete copy and move, to ensure it cannot be moved
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
};
Foo getFoo() {
return Foo();
}
int main() {
Foo* ptr = new Foo(getFoo());
std::cout << "Foo ptr is at " << (void*)ptr << '\n';
delete ptr;
}
This code outputs:
I am at 0x201ee70
Foo ptr is at 0x201ee70
And we see that Foo remains at the same location for the duration of it's lifetime, without ever being copied or moved, even though it's being created in dynamically allocated memory.
If a function returns a type that is not trivially copyable, then that function takes an implicit parameter representing the memory address where it's supposed to construct the return value.