C++ Copy Elision | When Copies and Moves Disappear

C++ Copy Elision | When Copies and Moves Disappear

이 글의 핵심

How compilers eliminate copy/move operations and what the standard guarantees since C++17.

Introduction

Copy elision removes unnecessary copy/move operations. Since C++17, certain prvalue flows must elide copies/moves as specified by the “guaranteed copy elision” rules.

Kinds of elision

RVO — return of prvalue

Widget create() {
    return Widget();  // prvalue
}

NRVO — named local

Widget create() {
    Widget w;
    return w;  // often elided; not always guaranteed like prvalue elision
}

Function arguments

void process(Widget w);
process(Widget());  // often constructs `w` directly

C++17 and prvalues

Returning prvalues and certain initializations must not introduce extra copy/move in the mandated cases—types may even be non-copyable if only moves/prvalue paths are used legally per standard rules.

Common mistakes

std::move on return of local

Widget bad() {
    Widget w;
    return std::move(w);  // often worse: can inhibit NRVO, forces move
}

Widget good() {
    Widget w;
    return w;
}

Multiple return objects

Returning different locals on different paths can prevent NRVO.

Compiler switches

-fno-elide-constructors (GCC/Clang) disables elision for debugging constructor traces.


  • RVO/NRVO
  • Move semantics

Keywords

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

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3