Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara 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

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 3. Capitolo 2

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

bookReturn Value Optimization (RVO) and NRVO

Scorri per mostrare il menu

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

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 3. Capitolo 2
some-alt