I was testing out the Return Value Optimizations in C++ Visual Studio 2022. I was surprised that the following program needed to call the copy constructor:
#include <iostream>
class A {
public:
A() { std::cout << "Constructor calling" << std::endl; }
A(A& a) { std::cout << "Copy Constructor calling" << std::endl; }
A(const A& a) { std::cout << "const Copy Constructor calling" << std::endl; }
};
A& getA() { A a; return a; }
int main() {
A a = getA();
return 0;
}
This outputs Constructor Calling\nCopy Constructor Calling
, which means it did not get optimized with NRVO. Yet when I change the program to the following (just removed the return by reference on getA()
):
#include <iostream>
class A {
public:
A() { std::cout << "Constructor calling" << std::endl; }
A(A& a) { std::cout << "Copy Constructor calling" << std::endl; }
A(const A& a) { std::cout << "const Copy Constructor calling" << std::endl; }
};
A getA() { A a; return a; }
int main() {
A a = getA();
return 0;
}
Now we get the output as just Constructor calling
and no calls to the copy constructor. Why does it not get optimized when I am returning by reference?