Destructor calling order from function calls different from <Effective C++>

Z

Zongjun Qi

Hey,

In the book <Effective C++>, the author provides an example to prove
why we need "pass by reference". I redoed the example, and found
something interesting. The codes are:
##############################
#include <iostream>

class Student{
public:
Student(){
std::cout << "inside CTOR. this = " << this << std::endl <<
std::endl;
}

Student(const Student& rhs){
std::cout << "inside COPY CTOR. this = " << this << ", rhs =
"<< &rhs << std::endl << std::endl;
}

~Student(){
std::cout << "inside DTOR. this = " << this << std::endl <<
std::endl;
}
};

Student ReturnStudent(Student s){
std::cout << "inside 'ReturnStudent' function" << std::endl <<
std::endl;
return s;
}

int main(){
Student Plato;
ReturnStudent(Plato);
std::cout << "outside 'ReturnStudent' function" << std::endl <<
std::endl;
}
###########################

The thing is when you run it, I got the following output:
inside CTOR. this = 0xbfff6e30



inside COPY CTOR. this = 0xbfff6e10, rhs = 0xbfff6e30



inside 'ReturnStudent' function



inside COPY CTOR. this = 0xbfff6e20, rhs = 0xbfff6e10



inside DTOR. this = 0xbfff6e20



inside DTOR. this = 0xbfff6e10



outside 'ReturnStudent' function



inside DTOR. this = 0xbfff6e30
################################
Which means DTOR of the returned value called actually 'BEFORE' DTOR of
's' called inside the ReturnStudent function, and this is differenct to
the author said, and which I originally believed.

I am using G++ 3.2.3, Linux 2.4.21-32.EL. Compile the program using
"g++ -g main.cpp", not without any optimization.
 
A

Alf P. Steinbach

* Zongjun Qi:
Hey,

In the book <Effective C++>, the author provides an example to prove
why we need "pass by reference". I redoed the example, and found
something interesting. The codes are:
##############################
#include <iostream>

class Student{
public:
Student(){
std::cout << "inside CTOR. this = " << this << std::endl <<
std::endl;
}

Student(const Student& rhs){
std::cout << "inside COPY CTOR. this = " << this << ", rhs =
"<< &rhs << std::endl << std::endl;
}

~Student(){
std::cout << "inside DTOR. this = " << this << std::endl <<
std::endl;
}
};

Student ReturnStudent(Student s){
std::cout << "inside 'ReturnStudent' function" << std::endl <<
std::endl;
return s;
}

int main(){
Student Plato;
ReturnStudent(Plato);
std::cout << "outside 'ReturnStudent' function" << std::endl <<
std::endl;
}
###########################

The thing is when you run it, I got the following output:
inside CTOR. this = 0xbfff6e30



inside COPY CTOR. this = 0xbfff6e10, rhs = 0xbfff6e30



inside 'ReturnStudent' function



inside COPY CTOR. this = 0xbfff6e20, rhs = 0xbfff6e10



inside DTOR. this = 0xbfff6e20



inside DTOR. this = 0xbfff6e10



outside 'ReturnStudent' function



inside DTOR. this = 0xbfff6e30
################################
Which means DTOR of the returned value called actually 'BEFORE' DTOR of
's' called inside the ReturnStudent function, and this is differenct to
the author said, and which I originally believed.

I am using G++ 3.2.3, Linux 2.4.21-32.EL. Compile the program using
"g++ -g main.cpp", not without any optimization.

I don't believe Scott Meyers have written that the output must be
different from you got above. It's much more likely that you have
misinterpreted what he wrote. Here are the rules:

* Destructors of automatic objects (all objects in your program are
automatic) are called in opposite order of construction.

* Destructors of static objects are also called in opposite order of
construction.

* If you have both automatic and static objects, then the two rules
above allow, as a logical consequence of the possibility of local
static objects, that constructions and destructions sequences
such as A(), B(), ~A(), ~B() can occur, i.e. not strictly nested.

In your program destructors are called in opposite order of construction.

That's correct behavior.
 
Z

Zongjun Qi

Alf,

Thanks for your explanation. That explains well the output from G++.
However, what Meyer says in the book is a little differenct as I stated
above. But THAT' S OKAY. I guess that's a minor mistake. I think you
are right in listing the right order.

Thanks,
Zongjun
 
S

Salt_Peter

Zongjun said:
Hey,

In the book <Effective C++>, the author provides an example to prove
why we need "pass by reference". I redoed the example, and found
something interesting. The codes are:
##############################
#include <iostream>

class Student{
public:
Student(){
std::cout << "inside CTOR. this = " << this << std::endl <<
std::endl;
}

Student(const Student& rhs){
std::cout << "inside COPY CTOR. this = " << this << ", rhs =
"<< &rhs << std::endl << std::endl;
}

~Student(){
std::cout << "inside DTOR. this = " << this << std::endl <<
std::endl;
}
};

Student ReturnStudent(Student s){
std::cout << "inside 'ReturnStudent' function" << std::endl <<
std::endl;
return s;
}

int main(){
Student Plato;
ReturnStudent(Plato);
std::cout << "outside 'ReturnStudent' function" << std::endl <<
std::endl;
}
###########################

The thing is when you run it, I got the following output:
inside CTOR. this = 0xbfff6e30



inside COPY CTOR. this = 0xbfff6e10, rhs = 0xbfff6e30



inside 'ReturnStudent' function



inside COPY CTOR. this = 0xbfff6e20, rhs = 0xbfff6e10



inside DTOR. this = 0xbfff6e20



inside DTOR. this = 0xbfff6e10



outside 'ReturnStudent' function



inside DTOR. this = 0xbfff6e30
################################
Which means DTOR of the returned value called actually 'BEFORE' DTOR of
's' called inside the ReturnStudent function, and this is differenct to
the author said, and which I originally believed.

I am using G++ 3.2.3, Linux 2.4.21-32.EL. Compile the program using
"g++ -g main.cpp", not without any optimization.

The above is better explained by:

int main(){
Student Plato;
Student me = ReturnStudent(Plato);
std::cout << "outside 'ReturnStudent' function" << std::endl <<
std::endl;
}

The intended sequence of destruction now occurs correctly. Without the
Student me, the compiler just zaps both the dropped returned student
and the original parameter as fast as it can.
By the way, the author is not focusing on the sequence, its the fact
that Student, when copied, invokes the ctors for each one of its
members as well.
He's refering to the "cost" of passing by value. Members need to be
destroyed too.
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top