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
6
votes
2 answers

Move Constructor vs Copy Elision. Which one gets called?

I have two pieces of code here to show you. They are two classes and each one provides a Move Constructor and a function which returns a temporary. In the first case, the function returning a temporary calls the Move Constructor In the second case,…
gedamial
  • 1,498
  • 1
  • 15
  • 30
6
votes
2 answers

Returning temporaries of type with deleted move/copy ctor

Consider the following program: #include using namespace std; struct S { S() = default; S(const S& other) = delete; S(S&& other) = delete; int i; }; S nakedBrace() { return {}; // no S constructed here? } S…
Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
6
votes
2 answers

Will any compiler actually ever elide these copies?

Given struct Range{ Range(double from, double to) : from(from), to(to) {} double from; double to; // if it matters to the compiler, we can add more fields here to make copying expensive }; struct Box{ Box(Range x, Range y) :…
Museful
  • 6,711
  • 5
  • 42
  • 68
6
votes
1 answer

gcc and clang both elide the call to the move constructor in the snippet below. Is this correct?

In the code below an object s of class S is used to initialize an object of class D with a direct-initialization D d(s);. The conversion function S::operator D() is used to convert the object s into a temporary object of type D. Then, gcc and clang…
Belloc
  • 6,318
  • 3
  • 22
  • 52
6
votes
1 answer

std::pair move not elided on definition?

I noticed something very strange with Visual Studio 2012: Defining a pair object like so: auto objp = pair(); will not elide the copy/move of the pair in VC11, this call will print: LogMe::LogMe - def.ctor! LogMe::LogMe -…
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
6
votes
3 answers

Copy elision on Visual C++ 2010 Beta 2

I was reading Want Speed? Pass by Value on the C++ Next blog and created this program to get a feel for copy elision and move semantics in C++0x: #include #include class MoveableClass { public: MoveableClass() :…
dvide
  • 437
  • 4
  • 8
5
votes
1 answer

C++ 17 copy elision of heap allocated objects?

I'm using C++ 17 and I have a rather large (two dimensional) array of numbers I'm trying to initialize at the namespace scope. This array is intended to be a pre-computed lookup table that's going to be used in many parts of my code. It's definition…
Christian Daley
  • 779
  • 2
  • 9
  • 13
5
votes
1 answer

Copy elision in initializer list?

Consider this class class A { public: tracker tra; A(tracker _t) : tra(_t) {} }; And call it through A a {tracker()}; The object created by tracker() is never used until being stored in a.tra Why don't the compiler optimize all the copy…
aleck099
  • 428
  • 2
  • 10
5
votes
3 answers

When is a move constructor called in practice?

I've recently learned about move constructors, but a lot of the online resources don't talk about copy elision. Copy elision makes sense to me too, but it left me wondering when is the move constructor ever going to be called without a super…
Joshua Segal
  • 541
  • 1
  • 7
  • 19
5
votes
2 answers

Why does Return Value Optimization not happen if no destructor is defined?

I expected to see copy elision from Named Return Value Optimization (NRVO) from this test program but its output is "Addresses do not match!" so NRVO didn't happen. Why is this? // test.cpp // Compile using: // g++ -Wall -std=c++17 -o test…
Ben C
  • 658
  • 6
  • 18
5
votes
1 answer

Guaranteed copy elision and forward declaration of returned type

I want to write a common interface using CRTP, for all types that define some group of functions. The following code does not compile, because I call a function before the definition of its returned type: // interface.h struct Obj; template…
Thibaud
  • 101
  • 7
5
votes
1 answer

Const-correctness for non trivial variables

(kind of inspired by this answer although not related) I've always been told (and been telling) that keeping const-correctness, even for short lived variables is valuable and good practice, e.g: const std::string a = "Hello world"; Instead…
Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
5
votes
1 answer

Implicit conversion operator vs template constructor - who should be prioritized?

Consider the following code snippet: template struct dependent_false { static constexpr auto value = false; }; struct foo { foo() { } template foo(const T&) { static_assert(dependent_false::value, "");…
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
5
votes
4 answers

Why was the code required to have an accessible copy/move constructor even when copy-elision was permitted to happen?

Nicol Bolas wrote the following in his answer in SO: Copy elision was permitted to happen under a number of circumstances. However, even if it was permitted, the code still had to be able to work as if the copy were not elided. Namely, there…
Wake up Brazil
  • 3,421
  • 12
  • 19
5
votes
1 answer

While doing copy-elision, the compiler doesn't consider the copy constructor in overload resolution, when the move constructor is deleted. Why?

I can understand the compiler is doing copy-elision in the code below, as the copy and move constructors are not invoked in the so called copy-initialization done in main(). See live example. #include struct S { S() = default; …