Basic question C++ exception

Discussion in 'C++' started by Vijay, Jun 29, 2008.

  1. Vijay

    Vijay Guest

    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,
    Vijay, Jun 29, 2008
    #1
    1. Advertising

  2. On 2008-06-29 17:34, Vijay wrote:
    > 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

    --
    Erik Wikström
    Erik Wikström, Jun 29, 2008
    #2
    1. Advertising

  3. Vijay

    Guest

    On Jun 29, 11:34 am, Vijay <> wrote:
    > 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?
    , Jun 29, 2008
    #3
  4. Vijay

    Vijay Guest

    On Jun 29, 12:41 pm, Erik Wikström <> wrote:
    > On 2008-06-29 17:34, Vijay wrote:
    >
    >
    >
    > > 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.


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


    >
    > > 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


    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 :)
    >
    > --
    > Erik Wikström
    Vijay, Jun 29, 2008
    #4
  5. Vijay

    Vijay Guest

    On Jun 29, 12:44 pm, "" <>
    wrote:
    > On Jun 29, 11:34 am, Vijay <> wrote:
    >
    >
    >
    > > 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?


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

    regards
    Vijay, Jun 29, 2008
    #5
  6. On 2008-06-29 20:28, Vijay wrote:
    > On Jun 29, 12:41 pm, Erik Wikström <> wrote:
    >> On 2008-06-29 17:34, Vijay wrote:


    >> > 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

    >
    > 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).

    --
    Erik Wikström
    Erik Wikström, Jun 29, 2008
    #6
  7. Vijay

    Vijay Guest

    On Jun 29, 2:55 pm, Erik Wikström <> wrote:
    > On 2008-06-29 20:28, Vijay wrote:
    >
    >
    >
    > > On Jun 29, 12:41 pm, Erik Wikström <> wrote:
    > >> On 2008-06-29 17:34, Vijay wrote:
    > >> > 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

    >
    > > 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).
    >

    Got it. Thanks :)
    > --
    > Erik Wikström
    Vijay, Jun 29, 2008
    #7
  8. Vijay

    James Kanze Guest

    On Jun 29, 8:28 pm, Vijay <> wrote:
    > On Jun 29, 12:41 pm, Erik Wikström <> 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 30, 2008
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Satterwhite

    (Very) Basic question re: exception

    Michael Satterwhite, Apr 21, 2004, in forum: C++
    Replies:
    6
    Views:
    474
    John Carson
    Apr 21, 2004
  2. Engineer
    Replies:
    6
    Views:
    611
    Jeremy Bowers
    May 1, 2005
  3. Replies:
    0
    Views:
    427
  4. Replies:
    3
    Views:
    348
    =?iso-8859-1?q?Erik_Wikstr=F6m?=
    Jun 13, 2007
  5. Daniel Koch
    Replies:
    3
    Views:
    369
    Andrey Tarasevich
    Nov 25, 2008
Loading...

Share This Page