C++ RVO and NRVO | Return Value Optimization Guide
이 글의 핵심
How return-value optimization works, what C++17 guarantees, and when NRVO is optional.
What are RVO and NRVO?
RVO (Return Value Optimization) applies when returning temporaries. NRVO (Named Return Value Optimization) applies when returning a named local variable. Together they are the main examples of copy elision.
BigObject createObject() {
return BigObject(); // RVO — prvalue
}
BigObject createNamed() {
BigObject obj;
return obj; // NRVO — named object
}
RVO vs NRVO
| Optimization | Return form | C++17 mandatory | Notes |
|---|---|---|---|
| RVO | Temporary object | Yes (prvalue) | Very reliable |
| NRVO | Named variable | No | Same variable, same type paths |
graph TD
A[Function Return] --> B{Return Form}
B -->|return Type...| C[RVO]
C --> D[C++17 guaranteed]
D --> E[0 copy/move]
B -->|return obj| F{Conditions}
F -->|Single var| G[NRVO attempt]
F -->|Multiple vars| H[Often move/copy]
G --> I{Compiler}
I -->|OK| E
I -->|No| J[Move ctor]
C++17 guaranteed elision (prvalues)
Returning prvalues and certain initialization forms must not introduce extra copies/moves beyond the mandatory rules—see the standard’s “guaranteed copy elision” rules.
Examples
Vectors and strings
std::vector<int> createVector(size_t n) {
return std::vector<int>(n, 0);
}
std::string toUpper(std::string s) {
// transform s...
return s; // often NRVO
}
Factory with unique_ptr
template<typename T, typename... Args>
std::unique_ptr<T> make(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
When optimization fails
- Returning
std::move(local)from a local variable can prevent NRVO. - Multiple return paths returning different locals of the same type can block NRVO.
Related posts
- Copy elision
- Return statement
Keywords
C++, RVO, NRVO, copy elision, C++17