C++ RVO and NRVO | Return Value Optimization Guide

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

OptimizationReturn formC++17 mandatoryNotes
RVOTemporary objectYes (prvalue)Very reliable
NRVONamed variableNoSame 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.

  • Copy elision
  • Return statement

Keywords

C++, RVO, NRVO, copy elision, C++17