Why return by reference disables NRVO

Viewed 37

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?

0 Answers
Related