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

C++C++11

C++ Problem Overview


#include <stdio.h>
#include <array>
#include <vector>

std::vector<int> foo() {
 int i;
 std::vector<int> a(100);
 printf("%p, %p, %p\n", &i, &a, &(a[0]));
 return a;
}

int main() {
 int i;
 std::vector<int> b = foo();
 printf("%p, %p, %p\n", &i, &b, &(b[0]));
}

Why do a and b have the same address for the above? Is this some kind of "cross-stack-frame" optimization? The result is the same even when I use the -O0 option.

The output:

$ vim main.cpp 
$ cc -std=c++11 -lc++ main.cpp
$ ./a.out
0x7ffee28d28ac, 0x7ffee28d28f0, 0x7ff401402c00
0x7ffee28d290c, 0x7ffee28d28f0, 0x7ff401402c00
$ 

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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.

Solution 3 - C++

as the others have explained this is because of copy elison. You can disable that with g++ by:

g++ -fno-elide-constructors main.cpp

where main.cpp contains your code.

now a and b have different addresses but a[0] and b[0] will have the same address because of the move semantics.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwillzengView Question on Stackoverflow
Solution 1 - C++Werner HenzeView Answer on Stackoverflow
Solution 2 - C++R.. GitHub STOP HELPING ICEView Answer on Stackoverflow
Solution 3 - C++Hikmat FarhatView Answer on Stackoverflow