Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are copy elision and return value optimization?

What is copy elision? What is (named) return value optimization? What do they imply?

In what situations can they occur? What are limitations?

  • If you were referenced to this question, you're probably looking for the introduction.
  • For a technical overview, see the standard reference.
  • See common cases here.
like image 716
Luchian Grigore Avatar asked Oct 18 '12 11:10

Luchian Grigore


People also ask

What is copy move elision?

C++ Copy Elision Purpose of copy elision Copy elision (sometimes called return value optimization) is an optimization whereby, under certain specific circumstances, a compiler is permitted to avoid the copy or move even though the standard says that it must happen.

What is return object optimization?

In the context of the C++ programming language, return value optimization (RVO) is a compiler optimization that involves eliminating the temporary object created to hold a function's return value. RVO is allowed to change the observable behaviour of the resulting program by the C++ standard.

How is copy elision implemented?

When copy elision occurs, the implementation treats the source and target of the omitted copy/move (since C++11) operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the ...

How does RVO work?

RVO is a compiler technique to avoid copying objects when the object is returned as function value. This optimization helps a function to efficiently return large objects while also simplifying the function's interface and eliminating scope for errors.


1 Answers

Introduction

For a technical overview - skip to this answer.

For common cases where copy elision occurs - skip to this answer.

Copy elision is an optimization implemented by most compilers to prevent extra (potentially expensive) copies in certain situations. It makes returning by value or pass-by-value feasible in practice (restrictions apply).

It's the only form of optimization that elides (ha!) the as-if rule - copy elision can be applied even if copying/moving the object has side-effects.

The following example taken from Wikipedia:

struct C {   C() {}   C(const C&) { std::cout << "A copy was made.\n"; } };   C f() {   return C(); }   int main() {   std::cout << "Hello World!\n";   C obj = f(); } 

Depending on the compiler & settings, the following outputs are all valid:

Hello World!
A copy was made.
A copy was made.


Hello World!
A copy was made.


Hello World!

This also means fewer objects can be created, so you also can't rely on a specific number of destructors being called. You shouldn't have critical logic inside copy/move-constructors or destructors, as you can't rely on them being called.

If a call to a copy or move constructor is elided, that constructor must still exist and must be accessible. This ensures that copy elision does not allow copying objects which are not normally copyable, e.g. because they have a private or deleted copy/move constructor.

C++17: As of C++17, Copy Elision is guaranteed when an object is returned directly:

struct C {   C() {}   C(const C&) { std::cout << "A copy was made.\n"; } };   C f() {   return C(); //Definitely performs copy elision } C g() {     C c;     return c; //Maybe performs copy elision }   int main() {   std::cout << "Hello World!\n";   C obj = f(); //Copy constructor isn't called } 
like image 88
Luchian Grigore Avatar answered Oct 02 '22 06:10

Luchian Grigore