Basic question C++ exception

V

Vijay

Hi All,

I am not able to figure out what exactly happening in below code. what
is control flow. Can anyone clear my confusion?

Code:
class A
{
public:
A(){cout<<"In Constructor\n";}
//// A(const A&){cout<<"In Copy Constructor\n";} // if we uncomment
this, we see different //output .
~A(){cout<<"In Destructor\n";}
};
try{
cout<<"In Try\n";
throw A();
}
catch(A &a)
{
cout<<"In Catch\n";
}
output:
In Try;
In Constructor
In Destructor
In Catch
In Destructor

Question 1. I don't know why two times destructor has been called. I
understand, since i am using reference, so there would not be any new
object. then why two times destructor got called.

Question 2.

class A
{
public:
A(){cout<<"In Constructor\n";}
A(const A&){cout<<"In Copy Constructor\n";}
~A(){cout<<"In Destructor\n";}
};
try{
cout<<"In Try\n";
throw A();
}
catch(A a)
{
cout<<"In Catch\n";
}
output:
In Try;
In Constructor
In Copy Constructor
In Catch
In Destructor
In Destructor

Why object created by throw A() has not been deleted while exiting try
block in above code?

thanks in advance.

Regards,
 
E

Erik Wikström

Hi All,

I am not able to figure out what exactly happening in below code. what
is control flow. Can anyone clear my confusion?

Code:
class A
{
public:
A(){cout<<"In Constructor\n";}
//// A(const A&){cout<<"In Copy Constructor\n";} // if we uncomment
this, we see different //output .
~A(){cout<<"In Destructor\n";}
};
try{
cout<<"In Try\n";
throw A();
}
catch(A &a)
{
cout<<"In Catch\n";
}
output:
In Try;
In Constructor
In Destructor
In Catch
In Destructor

Question 1. I don't know why two times destructor has been called. I
understand, since i am using reference, so there would not be any new
object. then why two times destructor got called.

The throw-expression creates a temporary object (the exception object)
using the copy-constructor and that is the one destroyed after the
handler has run. The compiler is however allowed to optimise away the
extra object, what is funny is that my compiler chooses to do so only
when I uncomment the copy-constructor.
Question 2.

class A
{
public:
A(){cout<<"In Constructor\n";}
A(const A&){cout<<"In Copy Constructor\n";}
~A(){cout<<"In Destructor\n";}
};
try{
cout<<"In Try\n";
throw A();
}
catch(A a)
{
cout<<"In Catch\n";
}
output:
In Try;
In Constructor
In Copy Constructor
In Catch
In Destructor
In Destructor

Why object created by throw A() has not been deleted while exiting try
block in above code?

The object created by thow can not be destroyes before it has been used
to initialise the object in the exception-handler (the extra copy has
been eliminated). It will also live until the last exception handler has
run (if the object is destroyed and you re-throw what would happen
then?), so it is the last destructor to run.

If I comment out the copy-constructor my compiler does not optimise away
the extra copy and I get the following result:

In Try
In Constructor // throw A(), followed by a copy-constructor
In Destructor // The object created by A() is destroyed
In Catch // a in the catch(A a) is copy-constructed first
In Destructor // The object created in the handler is destroyes
In Destructor // The exception object dies
 
A

AnonMail2005

Hi All,

I am not able to figure out what exactly happening in below code. what
is control flow. Can anyone clear my confusion?

Code:
class A
{
public:
        A(){cout<<"In Constructor\n";}
////    A(const A&){cout<<"In Copy Constructor\n";} // if we uncomment
this, we see different //output .
         ~A(){cout<<"In Destructor\n";}};

try{
        cout<<"In Try\n";
        throw A();
        }
catch(A &a)
{
        cout<<"In Catch\n";}

output:
In Try;
In Constructor
In Destructor
In Catch
In Destructor

Question 1. I don't know why two times destructor has been called. I
understand, since i am using reference, so there would not be any new
object. then why two times destructor got called.

Question 2.

class A
{
public:
        A(){cout<<"In Constructor\n";}
       A(const A&){cout<<"In Copy Constructor\n";}
         ~A(){cout<<"In Destructor\n";}};

try{
        cout<<"In Try\n";
        throw A();
        }
catch(A a)
{
        cout<<"In Catch\n";}

output:
In Try;
In Constructor
In Copy Constructor
In Catch
In Destructor
In Destructor

Why object created by throw A() has not been deleted while exiting try
block in above code?

thanks in advance.

Regards,

In the first case, there has to be copy since you are getting two
destructor
calls. The copy is done using the default copy constructor which
doesn't
print any output. Makes sense to me.

I'm not sure why the order of the destructors are different in the
second
example. Could it have anything to do with the fact that the code you
posted for the second example is catching the exception by value? Or
is the missing '&' a typo?
 
V

Vijay

The throw-expression creates a temporary object (the exception object)
using the copy-constructor and that is the one destroyed after the
handler has run. The compiler is however allowed to optimise away the
extra object, what is funny is that my compiler chooses to do so only
when I uncomment the copy-constructor.

yes. even i was thinking same. but was confused why compiler shows
different behavior after uncommenting the copy constructor. Thanks for
you reply

The object created by thow can not be destroyes before it has been used
to initialise the object in the exception-handler (the extra copy has
been eliminated). It will also live until the last exception handler has
run (if the object is destroyed and you re-throw what would happen
then?), so it is the last destructor to run.

If I comment out the copy-constructor my compiler does not optimise away
the extra copy and I get the following result:

In Try
In Constructor     // throw A(), followed by a copy-constructor
In Destructor      // The object created by A() is destroyed
In Catch           // a in the catch(A a) is copy-constructed first
In Destructor      // The object created in the handler is destroyes
In Destructor      // The exception object dies

Thanks. I think, because of compiler optimization, i am getting
confused.
one more point: in your above result, i didnt get two lines
In Destructor // The object created by A() is destroyed
and
In Destructor // The exception object dies

object created by A() is exception object. right?
If no, then when exception object is created which dies in last line?

Thanks a lot :)
 
V

Vijay

In the first case, there has to be copy since you are getting two
destructor
calls.  The copy is done using the default copy constructor which
doesn't
print any output.  Makes sense to me.

I'm not sure why the order of the destructors are different in the
second
example.  Could it have anything to do with the fact that the code you
posted for the second example is catching the exception by value?  Or
is the missing '&' a typo?

Thanks for ur reply. there was no typo.. I want to catching the
exception by value.

regards
 
E

Erik Wikström

Thanks. I think, because of compiler optimization, i am getting
confused.
one more point: in your above result, i didnt get two lines
In Destructor // The object created by A() is destroyed
and
In Destructor // The exception object dies

object created by A() is exception object. right?
If no, then when exception object is created which dies in last line?

No, the exception object is a copy of the object created by A(), unless
the compiler uses the optimisation, in which case the exception-object
and the object created by A() is the same (and in that case it will no
be destroyed until the end of the exception-handler).
 
V

Vijay

No, the exception object is a copy of the object created by A(), unless
the compiler uses the optimisation, in which case the exception-object
and the object created by A() is the same (and in that case it will no
be destroyed until the end of the exception-handler).
Got it. Thanks :)
 
J

James Kanze

On Jun 29, 12:41 pm, Erik Wikström <[email protected]> wrote:

[...]
Thanks. I think, because of compiler optimization, i am getting
confused.
one more point: in your above result, i didnt get two lines
In Destructor // The object created by A() is destroyed
and
In Destructor // The exception object dies

object created by A() is exception object. right?
If no, then when exception object is created which dies in last line?

Just a note, but in such experimenting, I would recommend
outputting the this pointer in your trace output. That way, you
can easily see which destructors are for which objects.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top