Jump to content

Copy elision

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Overdamped (talk | contribs) at 15:19, 29 June 2011 (Improved flow). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

In C++ computer programming, copy elision refers to a compiler optimization technique that eliminates unnecessary copying of objects. The C++ language standard generally allows implementations to perform any optimization, as long as the resulting program's observable behavior is the same as if the program was executed exactly as mandated by the standard.

The standard also describes a few situations where copying can be eliminated even if this would alter the program's behavior, the most common being the return value optimization. Another widely implemented optimization, described in the C++ standard, is when a temporary object of class type is copied to an object of the same type.[1] As a result, copy-initialization is usually equivalent to direct-initialization in terms of performance, but not in semantics; copy-initialization still requires an accessible copy constructor.[2] The optimization can not be applied to a temporary object that has been bound to a reference. Example:

int n = 0;
struct C {
  C(int) {}
  C(const C&) { ++n; } // the copy constructor has a visible side effect
};                     // it modifies an object with static storage duration

int main() {
  C c1(42); // direct-initialization, calls C::C(42)
  C c2 = 42; // copy-initialization, calls C::C(42) _or_ C::C( C(42) )

  return n; // returns either 0 or 1, depending on whether the copy was elided
}

The standard also mentions that a similar optimization may be applied to objects being thrown and caught,[3][4] but it is unclear whether the optimization applies to both the copy from the thrown object to the exception object, and the copy from the exception object to the object declared in the exception-declaration of the catch clause. It is also unclear whether this optimization only applies to temporary objects, or named objects as well.[5] Given the following source 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) {  // copying the exception object into the temporary in the exception declaration.
  }             // It is also unclear whether this copy may be elided.
}

A conforming compiler should therefore produce a program that prints "Hello World!" twice. In the upcoming C++ standard (C++0x), the issues have been addressed, essentially allowing both the copy from the named object to the exception object, and the copy into the object declared in the exception handler to be elided.[5]

References

  1. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §12.8 Copying class objects [class.copy] para. 15
  2. ^ Sutter, Herb (2001). More Exceptional C++. Addison-Wesley.
  3. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §15.1 Throwing an exception [except.throw] para. 5
  4. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §15.3 Handling an exception [except.handle] para. 17
  5. ^ a b "C++ Standard Core Language Defect Reports". WG21. Retrieved 2009-03-27.