🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

3 total messages Started by Scott Meyers Fri, 10 Nov 1995 19:14
Re: Exceptions in destructors.
#2494
Author: Scott Meyers
Date: Fri, 10 Nov 1995 19:14
113 lines
3458 bytes
  >While trying to implement an exception-safe array class (and model it
  >on the built-in C style arrays as closely as possible), it occured to
  >me that the draft doesn't really have much to say about the case of
  >exceptions thrown in destructors.  Two cases occur to me:
  
  >	T               a[ 5 ] ;
  >
  >When destructing the third element (for example), an exception is
  >thrown.  Are the remaining elements destructed?  I would say yes.  
  
       I agree. "Stack unwinding" and "object unwinding" 
  (destruction) are closely related. If during destruction
  an exception is thrown, destruction continues (provided
  there is a reachable handler)

I'm inclined to disagree.  How is destruction to continue?  Suppose we
have this:

  try {
    T a[5];
  }
  catch (...) {
    // do something here
  }
  
Now suppose destruction of a[3] throws.  Do we go to the handler?  If
so, do we then go back into the try block to try destroying the rest of
a?  What if the handler does a rethrow, and the exception is not caught for
many stack frames.  After handling the exception, there is no context to
return to to continue destroying a.  I don't see how this can work.

If we don't go to the handler when a[3] throws, what if a[2]'s destructor
also throws?  Then we've got two active exceptions, and it's terminate
time.  

  thrown. As if:
  
      delete p;
  
  meant:
  
      try { p->~P(); }
      catch(...) {
        operator delete(p);
        throw;
      }
      operator delete(p);
  
  
  [Smly for array case?]

Does this imply that for an array, you're suggesting the above code
(more or less) be put inside an implicit loop that cyles through each
member of the array?  Doesn't the implicit catch(...) hijack any
client-provided exception handling?

As long as we're on the topic of exceptions in destructors, here's
another question.  If a derived class destructor throws an exception, do
member and base class destructors still get called? 

Consider this program:

  #include <iostream.h>
  
  class M {
  public:
    ~M() { cout << "M destructor\n"; }
  };
  
  class B {
    M m;
  public:
    ~B() { cout << "B destructor\n"; }
  };
  
  class D: public B {
    M m;
  public:
    ~D() { cout << "Starting D destructor\n"; 
           throw "Ouch!";
           cout << "Ending D destructor\n";
         }
  };
  
  int main()
  {
    D d;
    return 0;
  } 

When d is destroyed, D's destructor throws.  Are destructors
nevertheless called for D::m, the B part of d, and B::m?  My feeling is
the answer should be no, in the same way that the remainder of D's
destructor is not executed after the throw.  Different compilers do
different things, however.  Who knows what is supposed to happen?

Scott











---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Exceptions in destructors.
#2561
Author: Dick Menninger
Date: Tue, 14 Nov 1995 23:55
74 lines
3106 bytes

> ==========Scott Meyers, 11/10/95==========

 [snip]

>   >     T               a[ 5 ] ;
>   >
>   >When destructing the third element (for example), an exception is
>   >thrown.  Are the remaining elements destructed?  I would say yes.  

[another agreement deleted]

> I'm inclined to disagree.  How is destruction to continue?  Suppose we
> have this:
> 
>   try {
>     T a[5];
>   }
>   catch (...) {
>     // do something here
>   }
>   
> Now suppose destruction of a[3] throws.  Do we go to the handler?  If
> so, do we then go back into the try block to try destroying the rest of
> a?  What if the handler does a rethrow, and the exception is not
> caught for
> many stack frames.  After handling the exception, there is no
context to
> return to to continue destroying a.  I don't see how this can work.
> 
> If we don't go to the handler when a[3] throws, what if a[2]'s
destructor
> also throws?  Then we've got two active exceptions, and it's terminate
> time.  


Although the wisdom of continuing the backward destruction
of the array may be quite suspect, it seems that 15.2 of DWP
gives compilers no choice but to do that.  The danger seems
to be an inherent part of requiring exception handling
(including the destructor processing while unwinding) to be
exception-free.  Part of the problem here is that there can be
an environmental thing for class T (or that particular array)
that puts destruction of the other instances into the same
exception case.  If that is the case, the destructor for the
class has to do the initial catch and put the class into
a special state before rethrowing it.  Further, the exception
instance has to deal with notifying class T on its "final"
destruction.  If temporaries can get destroyed after copying
those are not "final" destructions.  The notification would
take the class out of the special state if appropriate.

If the problem is not environmental to T, then you must take
your chances, but the DWP seems to say compilers better
continue with destruction of the array.

A related question is:
Does the DWP require the frames to be unwound
while it looks for a handler that catches the exception,
so that if it does not find a valid catcher all frames
are still gracefully undone (barring another exception)?



Good Day
Dick
Dick.Menninger@DaytonOH.ATTGIS.COM


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: Exceptions in destructors.
#2615
Author: Scott Meyers
Date: Wed, 15 Nov 1995 18:09
44 lines
2523 bytes
In article <DI24xB.756@falcon.daytonoh.attgis.com> mennid <Dick.Menninger@daytonoh.attgis.com> writes:
| Although the wisdom of continuing the backward destruction
| of the array may be quite suspect, it seems that 15.2 of DWP

For non-heap arrays, the DWP does seems to say that.  Is this reasonable?

| gives compilers no choice but to do that.  The danger seems
| to be an inherent part of requiring exception handling
| (including the destructor processing while unwinding) to be
| exception-free.  Part of the problem here is that there can be
| an environmental thing for class T (or that particular array)
| that puts destruction of the other instances into the same
| exception case.  If that is the case, the destructor for the

I don't understand this at all.  Can you elaborate?

| class has to do the initial catch and put the class into
| a special state before rethrowing it.  Further, the exception
| instance has to deal with notifying class T on its "final"
| destruction.  If temporaries can get destroyed after copying
| those are not "final" destructions.  The notification would
| take the class out of the special state if appropriate.
| 
| If the problem is not environmental to T, then you must take
| your chances, but the DWP seems to say compilers better
| continue with destruction of the array.
| 
| A related question is:
| Does the DWP require the frames to be unwound
| while it looks for a handler that catches the exception,
| so that if it does not find a valid catcher all frames
| are still gracefully undone (barring another exception)?

The DWP makes it clear that stack frames need not be unwound if no handler
is found, but if a handler is found, locals in intervening frames must have
been destroyed by the time the handler is entered.

Scott

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads