Questions tagged [copy-elision]

Copy elision refers to an exception to the as-if rule allowing to omit copies

Copy Elision is an exception to the as-if rule governing the behavior of C++ programs.

Return-value-optimization is copy-ellision applied to value-returns.

12.8 Copying and moving class objects [class.copy]

31 When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects. In such cases, the implementation treats the source and target of the omitted copy/move 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 optimization.123
This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

  • in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value
  • in a throw-expression, when the operand is the name of a non-volatile automatic object (other than a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one), the copy/move operation from the operand to the exception object (15.1) can be omitted by constructing the automatic object directly into the exception object
  • when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
  • when the exception-declaration of an exception handler (Clause 15) declares an object of the same type (except for cv-qualification) as the exception object (15.1), the copy operation can be omitted by treating the exception-declaration as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the exception-declaration.
272 questions
12
votes
1 answer

Overload-Resolution: Is a direct conversion operator preferred (as a consequence of copy-elision)?

Given struct E { }; struct P { explicit P(E) {} }; struct L { operator E() {return {};} operator P() {return P{E{}};} }; According to the C++17 language standard, should the expression P{L{}} compile? Different compilers produce…
12
votes
1 answer

Does C++17 forbid copy elision in a case where C++14 allowed it?

Consider the following: struct X { X() {} X(X&&) { puts("move"); } }; X x = X(); In C++14, the move could be elided despite the fact that the move constructor has side effects thanks to [class.copy]/31, This elision of copy/move operations…
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
12
votes
2 answers

How can a unique_ptr be returned by value without std::move?

std::unique_ptr ptr() { std::unique_ptr p(new int(3)); return p; // Why doesn't this require explicit move using std::move? } // Why didn't the data pointed to by 'p' is not destroyed here though p is not moved? int main() { …
Alex
  • 245
  • 1
  • 2
  • 6
11
votes
1 answer

Why does std::atomic compile from C++17 even with a deleted copy constructor?

I have a simple code: #include int main() { std::atomic a = 0; } This code compiles fine with GCC 11.1.0 with -std=c++17, but fails with -std=c++14 and -std=c++11. using a deleted function std::atomic::atomic(const…
Michal
  • 627
  • 3
  • 13
11
votes
2 answers

Why does copy initializaton require destructor in C++17 with guaranteed move/copy elision?

The following code compiles with MSVC (/permissive-) and fails to compile with GCC/Clang for m_ptr1 and m_ptr2. #include struct ForwardDeclared; class A { public: explicit A(); ~A(); private: …
JVApen
  • 11,008
  • 5
  • 31
  • 67
11
votes
2 answers

Why do I not get guaranteed copy elision with std::tuple?

I would expect that in C++20 the following code prints nothing between prints of A and B (since I expect guaranteed RVO to kick in). But output is: A Bye B C Bye Bye So presumably one temporary is being created. #include #include…
NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
11
votes
1 answer

Copy/move elision requires explicit definition of copy/move constructors

Consider the following program: #include #include class T { public: T() { printf("address at construction: %zx\n", (uintptr_t)this); } // T(const T&) { printf("copy-constructed\n"); } // helps // T(T&&) {…
Al Gebra
  • 173
  • 1
  • 7
11
votes
3 answers

Pass-by-value resulting in extra move

I'm trying to understand move semantics and copy/move elision. I would like a class that wraps up some data. I would like to pass the data in in the constructor and I would like to own the data. After reading this, this and this I got the impression…
Chris Drew
  • 14,926
  • 3
  • 34
  • 54
11
votes
1 answer

understanding c++11 rvalues, move semantics and performance

Possible Duplicate: What happens if I return literal instead of declared std::string? Consider the following code string getName () { return "meme"; } string name = getName(); The function getName() returns a temporary object. In C++03, I…
10
votes
1 answer

How does guaranteed copy elision work in list-initialization in C++1z?

There is a paragraph about guaranteed copy elision in c++ draft n4606 [dcl.init] 17.6: If the destination type is a (possibly cv-qualified) class type: If the initializer expression is a prvalue and the cv-unqualified version of the source…
Carousel
  • 728
  • 4
  • 13
10
votes
2 answers

Copy constructor is not called when return by value

I was playing around with C++ constructors. Here is my code: #include using namespace std; class ArrayWrapper { public: // default constructor produces a moderately sized array ArrayWrapper () : _p_vals( new int[ 64 ] ) …
seemuch
  • 633
  • 3
  • 8
  • 19
9
votes
2 answers

Copy Construction in Initializer Lists

I was exploring the ugly world of std::intializer_list. As far as I've understood from the standard: § 11.6.4: An object of type std::initializer_list is constructed from an initializer list as if the implementation generated and materialized…
BiagioF
  • 9,368
  • 2
  • 26
  • 50
9
votes
2 answers

Does the standard state that copies must be equivalent?

Suppose I have a weird string type, that either owns or doesn't own it's underlying buffer: class WeirdString { private: char* buffer; size_t length; size_t capacity; bool owns; public: // Non-owning constructor …
Barry
  • 286,269
  • 29
  • 621
  • 977
9
votes
2 answers

Copy constructor not called when initializing an object with return value of a function

Consider the following code: #include using namespace std; class A { public: int a; A(): a(5) { cout << "Constructor\n"; } A(const A &b) { a = b.a; …
1 2
3
18 19