copy elision method
Asked Answered
C

1

5

From the standard definition of copy elision method:

In C++ computer programming, copy elision refers to a compiler optimization technique that eliminates unnecessary copying of objects.

Let us consider following code:

#include <cstdlib>
#include <iostream>
using namespace std;
int n=0;
struct C 
{
 C (int) {}
 C(const C&) {++n;}      



       };
int main(int argc, char *argv[])
{
    C c1(42);
    C c2=42;




return n;
}

This line "return n" will returns either 0 or 1, depending on whether the copy was elided.

Also consider this code:

#include <iostream>

struct C {
  C() {}
  C(const C&) { std::cout << "Hello World!\n"; }
};

void f() {
  C c;
  throw c; // copying the named object c into the exception object.
}          // It is unclear whether this copy may be elided.

int main() {
  try {
    f();
  }
  catch(C c) { 
}
}

It says that

// copying the exception object into the temporary in the exception declaration.
//It is also unclear whether this copy may be elided.

So my question is how useful is implement such optimization method, if sometimes results are undefined? And in general how often it is used?

Charnel answered 30/9, 2011 at 8:2 Comment(2)
There isn't even a copy in your first example. For the second example: https://mcmap.net/q/1289798/-can-copy-elision-occur-in-catch-statements/46642Teratoid
@R.MartinhoFernandes: in the second example in this question (rather than your linked question) the same caveats as with NRVO occur: the copy from c to the internal storage for the exception can only be elided if the compiler can guarantee that the exception will be thrown when constructing the object c. And even there, the problem that the user has, as I understood it, is that the standard does not mandate that behavior, which means that you cannot depend on side effects of the copy constructor --which is something that the standard explicitly states anywayUrquhart
C
10

The important bit is that the standard explicitly allows for this, and that means that you cannot assume that the side effects of a copy constructor will be executed as the copies might be elided. The standard requires that the implementation of a copy-constructor has copy-constructor semantics, that is, has as whole purpose the generation of a second object semantically equivalent in your domain to the original object. If your program complies with that, then the optimization will not affect the program.

It is true, on the other hand, that this is the only situation I can think where the standard allows for different visible outcomes from the same program depending on what the compiler does, but you have been advised that you should not have side effects in your copy constructor (or rather, you cannot depend on the exact number of copies performed).

As to whether it is worth it, yes it is. In many cases copies are quite expensive (I am intentionally ignoring move-constructors in C++11 from the discussion). Consider a function that returns a vector<int>, if the copy is not elided, then another dynamic allocation is required, copy of all of the vector contents and then release of the original block of memory all three operations can be expensive.

Alternatively, you could force users to change their code to create an empty object and pass it by reference, but that will make code harder to read.

Coastwise answered 30/9, 2011 at 8:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.