Life of temporaries

B

bb

Hi,

Have a query regarding the life of temporaries. Here is the code...

class MyNumber {
public:
MyNumber(int n) : n(n) {
cout << "Object Constructed." << endl;
}

virtual ~MyNumber() {
cout << "Object Destructed." << endl;
}

MyNumber(const MyNumber& rhs) {
cout << "Object Copy Constructed." << endl;
n = rhs.getValue();
}

MyNumber& operator=(const MyNumber& rhs) {
if (this == &rhs) return *this;
cout << "Object Assigned." << endl;
n = rhs.getValue();
return *this;
}

int getValue() const {
return n;
}

private:
int n;
};

Main here...
-----------------

int main(int argc, char** argv) {

cout << "Understanding the life of temporaries..." << endl;

MyNumber mn1(9);
cout << "mn1: " << mn1.getValue() << endl;
MyNumber mn2 = mn1; // 'copy constructed' as expected
cout << "mn2: " << mn2.getValue() << endl;

cout << endl;
cout << "... Life of Temporaries ... case 1" << endl;
justReturn(mn1); // temporaries are 'destructed' on return as expected
cout << "... Life of Temporaries ... case 1" << endl;
cout << endl;

MyNumber mn3(0);
cout << endl;
cout << "... Life of Temporaries ... case 2" << endl;
mn3 = justReturn(mn1); // calls assignment operator as expected
cout << "... Life of Temporaries ... case 2" << endl;
cout << "mn3: " << mn3.getValue() << endl;

cout << endl;
cout << "... Life of Temporaries ... case 3" << endl;
MyNumber mn4 = justReturn(mn1); // not 'copy constructed', why?
cout << "... Life of Temporaries ... case 3" << endl;
cout << "mn4: " << mn4.getValue() << endl;

cout << endl;
cout << "Good bye" << endl;
}

// Receives the argument by value and returns the same by value
//
MyNumber justReturn(MyNumber mn) {
return mn;
}


The program output is as follows:
-------------------------------------------------

Understanding the life of temporaries...
Object Constructed.
mn1: 9
Object Copy Constructed.
mn2: 9

.... Life of Temporaries ... case 1
Object Copy Constructed.
Object Copy Constructed.
Object Destructed.
Object Destructed.
.... Life of Temporaries ... case 1

Object Constructed.

.... Life of Temporaries ... case 2
Object Copy Constructed.
Object Copy Constructed.
Object Assigned.
Object Destructed.
Object Destructed.
.... Life of Temporaries ... case 2
mn3: 9

.... Life of Temporaries ... case 3
Object Copy Constructed.
Object Copy Constructed.
Object Destructed.
.... Life of Temporaries ... case 3
mn4: 9

Good bye
Object Destructed.
Object Destructed.
Object Destructed.
Object Destructed.

-------- End of program output ----------

My questions:
-------------------

Am using gcc v4.0.2 on Redhat Fedora Core4 - 2.6.15

In case 3 above...

1. How is the object mn4 getting constructed? why there was no call to
the 'copy constructor'?

2. The 'returned' temporary is not destroyed immediately on return like
in other cases, why? it is actually getting destroyed much later at
the end of scope.

3. Is it due to some clever compiler optimization in gcc; kind of
aliasing happens between the returned temporary and mn4?

Thanks guys.
 
A

Alf P. Steinbach

* bb:
Hi,

Have a query regarding the life of temporaries. Here is the code...
[snip code]

The code as presented won't compile with any conforming compiler.

To obtain meaningful, quality answers, consider providing code that
actually compiles.

To do that, use "copy and paste" technique.


The program output is as follows:

[snip output]

My questions:
-------------------

Am using gcc v4.0.2 on Redhat Fedora Core4 - 2.6.15

In case 3 above...

1. How is the object mn4 getting constructed? why there was no call to
the 'copy constructor'?

Your output showed two copy constructor calls.

... Life of Temporaries ... case 3
Object Copy Constructed.
Object Copy Constructed.
Object Destructed.
... Life of Temporaries ... case 3
mn4: 9

How do you conclude from that output that there's no copy constructor call?

My conclusion is exactly opposite: that there is one (and in fact two).

2. The 'returned' temporary is not destroyed immediately on return like
in other cases, why?

You mean, there is a temporary that /is/ destroyed, as the output shows,
and you wonder why it is destroyed here.

C++ guarantees that temporaries last out the end of the full-expression,
and are destroyed before the end of the scope; within those rules a
compiler may choose when to destroy temporaries.

it is actually getting destroyed much later at
the end of scope.

The declared variable mn4 is destroyed at the end of the scope.

3. Is it due to some clever compiler optimization in gcc; kind of
aliasing happens between the returned temporary and mn4?

No.
 
L

loufoque

bb wrote :
Is it due to some clever compiler optimization in gcc


Yes.
GCC (like most compilers) performs return value optimization.
It actually doesn't use a temporary but stores directly the objet in the
variable which gets the return value.

You can disable it with -fno-elide-constructors
 
B

bb

Simply brilliant; both GCC and you.

With -fno-elide-constructors compile time option, it explains it all.

Thanks loufoque.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top