Why does an object returned by value have the same address as the object inside the method?

This is because of copy elision/named return value optimization (NRVO). foo returns a named object a. So the compiler is not creating a local object and returning a copy of it but creates the object at the place where the caller puts it. You can read more about it on https://en.cppreference.com/w/cpp/language/copy_elision. While RVO is mandatory since C++17, NRVO is not, but it looks like your compiler supports it even in case of -O0.


Note that even without copy elision (mandatory or not), it's already possible for the addresses of the two objects to be the same because their lifetimes are non-overlapping.