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