🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by David Byrden Mon, 05 Feb 1996 00:09
Can one do this in a handler???
#3248
Author: David Byrden
Date: Mon, 05 Feb 1996 00:09
89 lines
3729 bytes

I am studying the problem of writing exception-safe code,and have 
designed a small class which illustrates a technique of holding 
exceptions in abeyance while you continue to do some cleanup work. 

I wonder if anyone would examine the destructor of this class and tell 
me whether they can see it violating the C++ standard; I have of course 
examined that myself, but find it somewhat ambigous on the subject of 
exceptions caught by the ellipsis.


This template class owns a block of heap memory. The memory is allocated 
as an array of char; later, the placement "new" is used to construct T 
objects in the memory block. The Ts are all placed contigously from the 
start of the block, and the number of Ts in the block is remembered by a 
data member in the class.


template< class T>
class Tblock
{
   T* theBlock ;     // Start of the memory block
   int count  ;      // Number of T objects in it
   Tblock() ;
   ~Tblock() ;
} ;


The interesting part is the Tblock destructor. The destructor of class T 
is assumed to be able to throw exceptions, and I attempt to correctly 
destroy the Tblock object even when that happens.


template< class T >
Tblock<T>::~Tblock( )
{
   try
   {
      for(  count-- ; count >= 0 ; count-- )
         theBlock[count].~T() ;      // [a]
      delete [ ] static_cast<char*> theBlock ;
   }
   catch( ... )
   {
      ~Tblock( ) ;            // [b]
      throw ;
   }
}



Notes:

1  [a] and [b] are explicit destructor calls. I assume that this syntax 
   is correct because of the example of an explicit destructor call in 
   CopyConstructible Requirements  20.1.3.1
2  The intention is that the destructor shall explicitly destroy each T 
   object with an explicit destructor call, working down from the 
   highest-numbered T in the block to zero.
3  Any T may throw any exception from its destructor. In that case, we 
   go to the catch block and catch it with the intention of rethrowing 
   it later. 
4  The catch handler in the destructor explicitly calls the destructor 
   itself. The intended  effect of this is that the counter shall
   continue downwards, destroying the remaining T objects, while the 
   exception from the bad one remains in abeyance, waiting to be 
   rethrown.
5  The destructor call is recursive. Any and all of the T objects may 
   throw from its destructor, and yet the "good" ones will all be 
   destroyed,and finally the memory will be deleted. If exceptions 
   are thrown by any T objects, the most recently thrown one will 
   propagate out of the Tblock dtor.
6  Incidentally, it is illegal to remove the outermost brackets and make 
   the whole thing a function-try-block, because calling the destructor 
   from the handler would result in undefined behaviour.


          Thankyou


                             David



[ 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://reality.sgi.com/employees/austern_mti/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