Copy constructor?

Possible duplicate:
Why is the destructor called only once?

Given the code below, I don't understand the output in gcc. I expect two objects to be created and destroyed, but instead you will see only one call to the constructor and destructor. What's going on here?

#include <string> #include <iostream> struct Huge{ Huge() { std::cout << "Constructor" << std::endl; } Huge(Huge const &r) { std::cout << "Copy Constructor" << std::endl; } ~Huge() { std::cout << "Destructor" << std::endl; } }; Huge g() { std::cout << "Entering g" << std::endl; Huge temp; std::cout << "Exiting g" << std::endl; return temp; } int main(){ Huge h2(g()); std::cout << "Before leaving main" << std::endl; } 

The result of this code in g ++ (4.4) is

G input

Constructor

Exit g

Before leaving the main

destructor

+3
c ++ copy-constructor copy-elision
Jan 17 '12 at 6:24
source share
2 answers

Yes, this is copying using Named Optimization of the return value .

The C ++ standard allows an implementation to omit the copy operation obtained from the return statement, even if the copy constructor has side effects.

Link:

C ++ 03 standard:
12.8 Copying class objects:

# fifteen

When certain criteria are met, implementations are allowed to omit the copy construction of the class object, even if the copy constructor and / or destructor for the object have side effects. In such cases, the implementation considers the source and purpose of the missed copy operation as just two different ways to access the same object, and the destruction of this object occurs at later times when two objects would have been destroyed without optimization .111). This exclusion of copy operations is permitted in the following circumstances (which may be combined to eliminate multiple copies):

- in the return statement in a function with the type of the returned class, when the expression is the name of a non-volatile automatic object with the same cv-unqualified type as the returned type of the function, the copy operation can be omitted from constructing the automatic object directly to the return value of the function

- when the object of the temporary class that was not attached to the link (12.2) is copied to the object of the class with the same cv-unqualified type, the copy operation can be omitted by creating a temporary object directly in the target missed copy

+5
Jan 17 '12 at 6:27
source share

C ++ allows you to avoid creating and copying additional objects in cases like yours. This is called optimization of the named value. The fact is that you know for sure that after returning the temp object will disappear anyway, and the semantics of the copy constructor should make an equivalent copy of the original object.

Note that there are actually two optimizations here. Without optimization, the temp object will first be copied to the return value in g , and then the returned value will be copied to h2 in main . Named value optimization returns a copy to the return value. Copying from the return value to h2 is canceled because the return value is a temporary object, and copying can also be canceled here.

Please note that unlike other optimizations, these optimizations are allowed even if they change the observed behavior (as in your test program). This is because otherwise this optimization cannot be performed in many cases where it does not matter (indeed, with the exception of debugging output, it should never matter in a well-written program), because the compiler often cannot prove that elite would not change the observed behavior. On the other hand, there is no way to manually delete copies, so it is important that the compiler can do this automatically.

Ultimately, what happens is that the temp object is created directly in the h2 space, so there is already the correct value at the point of the return h2 operator. In other words, due to optimizations temp and h2 are actually the same object.

+1
Jan 17 '12 at 6:30
source share



All Articles