Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Return Value Optimization (RVO) and NRVO | Applied Move Semantics
Practice
Projects
Quizzes & Challenges
Quizzes
Challenges
/
C++ Move Semantics

bookReturn Value Optimization (RVO) and NRVO

Return Value Optimization (RVO) and Named Return Value Optimization (NRVO) are powerful compiler techniques that eliminate unnecessary copies or moves when returning objects from functions. By allowing the compiler to construct the return value directly in the memory space of the caller, these optimizations make move semantics even more efficient. This means that, in many cases, neither a copy nor a move constructor will be called when a function returns a local object.

main.cpp

main.cpp

copy
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
// Demonstrate RVO and move constructor calls #include <iostream> #include <string> class Widget { public: std::string name; Widget(const std::string& n) : name(n) { std::cout << "Constructed: " << name << '\n'; } Widget(const Widget& other) : name(other.name) { std::cout << "Copied: " << name << '\n'; } Widget(Widget&& other) noexcept : name(std::move(other.name)) { std::cout << "Moved: " << name << '\n'; } ~Widget() { std::cout << "Destroyed: " << name << '\n'; } }; // Function that returns a temporary (RVO applies) Widget makeWidgetRVO() { return Widget("RVO"); } // Function that returns a named local (NRVO may apply) Widget makeWidgetNRVO() { Widget w("NRVO"); return w; } // Function that disables RVO/NRVO (forces move) Widget makeWidgetNoRVO() { Widget w("No RVO"); // Returning via std::move disables RVO/NRVO return std::move(w); } int main() { std::cout << "-- RVO Test --\n"; Widget a = makeWidgetRVO(); std::cout << "-- NRVO Test --\n"; Widget b = makeWidgetNRVO(); std::cout << "-- No RVO Test --\n"; Widget c = makeWidgetNoRVO(); }

Watch the output to see if the move constructor is called. With RVO or NRVO, the compiler may construct the return value directly in the caller’s memory, skipping both move and copy constructors for efficiency.

Since C++17, RVO is mandatory in some cases, though NRVO remains an optimization. These optimizations make move constructors less common in practice, but you should still implement them for correctness and performance.

Note
Note

Whether RVO or NRVO occurs can depend on compiler settings and optimization levels, so behavior might vary between different builds or compilers.

question mark

What is the effect of Return Value Optimization (RVO) on move constructor calls when returning local objects from functions?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 2

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

bookReturn Value Optimization (RVO) and NRVO

Swipe um das Menü anzuzeigen

Return Value Optimization (RVO) and Named Return Value Optimization (NRVO) are powerful compiler techniques that eliminate unnecessary copies or moves when returning objects from functions. By allowing the compiler to construct the return value directly in the memory space of the caller, these optimizations make move semantics even more efficient. This means that, in many cases, neither a copy nor a move constructor will be called when a function returns a local object.

main.cpp

main.cpp

copy
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
// Demonstrate RVO and move constructor calls #include <iostream> #include <string> class Widget { public: std::string name; Widget(const std::string& n) : name(n) { std::cout << "Constructed: " << name << '\n'; } Widget(const Widget& other) : name(other.name) { std::cout << "Copied: " << name << '\n'; } Widget(Widget&& other) noexcept : name(std::move(other.name)) { std::cout << "Moved: " << name << '\n'; } ~Widget() { std::cout << "Destroyed: " << name << '\n'; } }; // Function that returns a temporary (RVO applies) Widget makeWidgetRVO() { return Widget("RVO"); } // Function that returns a named local (NRVO may apply) Widget makeWidgetNRVO() { Widget w("NRVO"); return w; } // Function that disables RVO/NRVO (forces move) Widget makeWidgetNoRVO() { Widget w("No RVO"); // Returning via std::move disables RVO/NRVO return std::move(w); } int main() { std::cout << "-- RVO Test --\n"; Widget a = makeWidgetRVO(); std::cout << "-- NRVO Test --\n"; Widget b = makeWidgetNRVO(); std::cout << "-- No RVO Test --\n"; Widget c = makeWidgetNoRVO(); }

Watch the output to see if the move constructor is called. With RVO or NRVO, the compiler may construct the return value directly in the caller’s memory, skipping both move and copy constructors for efficiency.

Since C++17, RVO is mandatory in some cases, though NRVO remains an optimization. These optimizations make move constructors less common in practice, but you should still implement them for correctness and performance.

Note
Note

Whether RVO or NRVO occurs can depend on compiler settings and optimization levels, so behavior might vary between different builds or compilers.

question mark

What is the effect of Return Value Optimization (RVO) on move constructor calls when returning local objects from functions?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 2
some-alt