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

copy elision causes different results

Suppose I have this hypothetical, odd and unintuitive situation #include struct A { A() { member = 1; } A(const A &) { member = 2; } int member; }; int…
SirGuy
  • 10,660
  • 2
  • 36
  • 66
2
votes
2 answers

Why does/ does not NRVO kick in g++ in the code below?

I have been looking into NRVO and it's support on different compilers, and came across strange behaviour, which is rather confusing. The sample code: #include using namespace std; class X { public: X() { …
relic
  • 175
  • 1
  • 1
  • 8
2
votes
3 answers

C++ return by value class objects's memory whereabouts in wake of optimizations

Let's say there is a user defined class Foo. Some posts suggest that a C++ class object is "never" allocated on heap unless allocated with new. But! on the other hand there are posts that suggest that returning a local looking class object by value…
2
votes
2 answers

Clang error: calling a private constructor while none of them were actually called

I made a static function of some class, and made constructor private. Now I want to use the function. Clang++ says "The constructor is private", while g++ compiles normally. I don't know if there are any rules in any Standard which could affect this…
Ya Ihniy
  • 23
  • 3
2
votes
2 answers

Does an implementation that returns fundamental types by value using registers do "temporary materialization"?

(c++20; Working Draft N4868) [stmt.return]/2 says that the return statement initializes the glvalue result or prvalue result object by copy initialization the return statement initializes the glvalue result or prvalue result object of the (explicit…
Manuel
  • 220
  • 3
  • 5
2
votes
2 answers

Why disabling copy elision for std::atomic doesn't work using C++17?

For std::atomic the copy constructor is deleted, and this should only compile with C++17 and higher due to copy elision: std::atomic t_int = 1; I expected that it does not compile using -fno-elide-constructors flag, but it still…
Ari
  • 7,251
  • 11
  • 40
  • 70
2
votes
1 answer

Shouldn't there be a copy ctor invocation here? Elision disabled (no named return value optimization)

struct Test { int field = 30; Test() { cout << "In ctor" << endl; } Test(const Test &other) { field = other.field; cout << "In copy ctor" << endl; } Test(Test &&other) { field = other.field; cout << "In move ctor" << endl; } Test…
bun9
  • 161
  • 8
2
votes
0 answers

Copy elision when initializing a base-class subobject with aggregate initialization

In the following code, struct B is an aggregate with base struct A, and B-object is aggregate initialized B b{ A{} }: #include struct A { A() { std::cout << "A "; } A(const A&) { std::cout << "Acopy "; } A(A&&) { std::cout <<…
Fedor
  • 17,146
  • 13
  • 40
  • 131
2
votes
1 answer

Where to use std::span?

I want to write a function that can accept any type of contiguous buffer (e.g. std::array, std::vector, raw array, etc) from its call site. I have come up with two methods. Method #1: void func( int* const buffer, const std::size_t…
digito_evo
  • 3,216
  • 2
  • 14
  • 42
2
votes
2 answers

Why doesn't automatic move work with function which return the value from rvalue reference input?

I already know automatic move is not woking with the function which return value from Rvalue Reference input. But why? Below is example code which automatic move is not working with. Widget makeWidget(Widget&& w) { .... return w; // Compiler…
myoldgrandpa
  • 871
  • 7
  • 21
2
votes
1 answer

Does static_cast(funcReturningT()) inhibit RVO?

C++17 guarantees copy elision for: T funcReturningT() { return T(...); } T t=funcReturningT(); Now if I wrap the return into a static_cast to the same type, like so: T t=static_cast(funcReturningT()); does the standard still guarantee copy…
Arno Schoedl
  • 159
  • 6
2
votes
0 answers

Copy elision with tuples

I always had the wrong impression that if I create temporaries in a function that returns a tuple, and use std::forward_as_tuple in the return statement, then there is no copy, just like automatic copy elision for non-tuple return types. How then…
fheshwfq
  • 303
  • 3
  • 11
2
votes
2 answers

Copy elision and operator overloading with C++

I have a struct such as: struct A { double x,y; vector vec; }; I would like to overload operators such as the plus operator so that I can perform operations such as: A a,b,c,d; //do work to set up the four structs. Then: d = a +…
pah52
  • 85
  • 6
2
votes
0 answers

Copy ellision of trivial type, bug in GCC?

I am doing some tests with trivial types with copy elision. As my prior question : Copy elision and trivially copyable types The following code works well for std::string but does not for const char*. Valgrind returns me "use of uninitialized value…
Antoine Morrier
  • 3,930
  • 16
  • 37
2
votes
1 answer

Unpredictable copy elision?

According to this Wiki page the following code: #include struct C { C() = default; C(const C&) { std::cout << "A copy was made.\n"; } }; C f() { return C(); } int main() { std::cout << "Hello World!\n"; C obj = f(); } may…
NPS
  • 6,003
  • 11
  • 53
  • 90