scope + destructor with Exception parameter for RAII

Sean Kelly sean at f4.ca
Tue Nov 28 14:34:43 PST 2006


Sean Kelly wrote:
> Pragma wrote:
>> BCS wrote:
>>> Sean Kelly wrote:
>>>> Leandro Lucarella wrote:
>>>>> What do you think of adding an optional parameter (exception) to 
>>>>> the destructor, defaulting to null, to indicate the destructor was 
>>>>> called then unwinding because an exception was thrown? Then you can 
>>>>> almost forget about scope(exit/success/failure) and you have a RAII 
>>>>> as complete  as Python's 'with' statement.
>>>>
>>>> I don't like it, personally.  It doesn't seem a good idea for a dtor 
>>>> to alter its behavior based on whether an exception is in flight, 
>>>> and exceptions should never be thrown from dtors anyway.  Doing so 
>>>> makes writing correct code far too complicated.
>>>>
>>>> One thing I have done for Ares, however, is to terminate the program 
>>>> if one exception is thrown while another is in flight.  I think 
>>>> DMD/Phobos does not do this currently, and instead either ignores 
>>>> the new exception, or substitutes it for the in-flight exception (I 
>>>> can't remember which).
>>>>
>>>>
>>>> Sean
>>>
>>>
>>> I think this works under DMD
>>>
>>> try
>>> {
>>>     throw new Error("some stuff");
>>> }
>>> catch(Error e)
>>> {
>>>     throw new Error("more stuff\n"~e.toString);
>>> }
>>>
>>>
>>> It could be vary handy to have this ability to swap out one exception 
>>> for another.
>>
>> Agreed.  Although I don't know if this interferes with Sean's 
>> interpretation of the spec or not.  I've done this in a few places 
>> myself, and I find it quite useful.
> 
> The above example isn't the same thing.  The in-flight exception is 
> caught and a different one is rethrown.  What I consider illegal is 
> something like this:
> 
>     try
>     {
>         throw new Exception( "A" );
>     }
>     finally
>     {
>         throw new Exception( "B" );
>     }

By the way, the change I made will only trap exceptions thrown from an 
object's dtor, as it was a change to the finalizer code.  The above will 
work just fine, with only one of the two exceptions escaping.  Same as:

     scope(exit) throw new Exception( "B" );
     throw new Exception( "A" );

I could probably be convinced that the throw from the finally block 
should simply be ignored, as the finally block is intended to do some 
simple clean-up, but the scope(exit) bit above is clearly a programming 
error.  Throwing from an object's dtor is a lot closer to throwing from 
scope(exit) than finally IMO.  Because while they are functionally 
identical, I think they are likely to be used in different ways.  With a 
finally block, the programmer is stating that he expects an exception to 
be thrown and that the code should execute regardless.  I'm still not 
certain that I like the idea of ignoring an exception from a finally 
block, but it bothers me less than ignoring exceptions from dtors or 
scope(exit)/scope(failure) blocks.


Sean



More information about the Digitalmars-d mailing list