Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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) : x(x), y(y) {}
    Range x;
    Range y;
};

someone said that in Box box(Range(0.0,1.0),Range(0.0,2.0)), the compiler can avoid copying Range objects altogether by constructing them inside box to begin with.

Does any compiler actually do this?

My own attempts haven't succeeded.

like image 334
Museful Avatar asked Nov 23 '15 14:11

Museful


People also ask

Is NRVO guaranteed?

Compilers often perform Named Return Value Optimization (NRVO) in such cases, but it is not guaranteed.

What is a guaranteed copy?

Guaranteed copy elision redefines a number of C++ concepts, such that certain circumstances where copies/moves could be elided don't actually provoke a copy/move at all. The compiler isn't eliding a copy; the standard says that no such copying could ever happen. Consider this function: T Func() {return T();}

What is temporary materialization?

Temporary materializationA prvalue of any complete type T can be converted to an xvalue of the same type T . This conversion initializes a temporary object of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object.


1 Answers

The compiler can - and normally does - elide the copies from the temporary to the argument. The compiler cannot elide the copy from the argument to members. While it may technically possible to elide these copies in some cases, the relevant permission isn't given. The section of the standard is 12.8 [class.copy] paragraph 31 which spells out 4 situations where a copy can be elided (the exact rules are a bit non-trivial):

  1. When returning a named, function local variable using it name.
  2. When using a named, function local variable in a throw expression.
  3. When copying a temporary object.
  4. When catching an exception by value.

Passing a named argument as parameter to the construction of a member variable is, clearly, none of these situations.

The essential background of the rules for copy elision is that in some contexts the declaration of functions suffice to determine when an object will be used. If it is clear upon construction time where the object can be constructed, it can be elided. The caller of a constructor cannot determine based only on the declaration of the constructor where the object will be used.

like image 118
Dietmar Kühl Avatar answered Nov 02 '22 05:11

Dietmar Kühl