Topic: Exceptions in ctors/dtors?


Author: dak <pierreba@poster.cae.ca>
Date: 1996/09/09
Raw View
Steve Clamage (clamage@taumet.Eng.Sun.COM) wrote:
> In article e2i@netlab.cs.rpi.edu,  Max Polk <maxpolk@worldnet.att.net> writes:
> >     Perhaps it is a bad idea ONLY because a bad rule exists that
> >terminate() will be called immediately.
>
> It's easy to call it a bad rule without suggesting an alternative.
> What do you suggest?
>
> Whatever you suggest as a replacement rule should be more usable and
> have generally better results than just calling terminate(). Here are
> a few things to consider.
>
> Suppose while unwinding the stack to handle exception 1, a
> destructor exits via exception 2. What should happen?

What about handling whichever exception handler is first encountered.
At first sight it might seem inappropriate but:

  - In the previous error handling scheme (either return value or
    static error record) that is what happened. The first block of
 code which handled any error was first executed, whatever the
 order of error.

  - There is not real hard reason why an error should be handled first
    just because it happened first. In fact, executing whichever handler
 comes first actually makes sense since the programmer chose in which
 order to handle the exceptions.

  - Innermost handler are ussually there to protect the rest of the
    world about a specific exception. Passing over it because its
 exception didn't come first might not be appropriate. Some very
 important code might be skipped.

[...]

>                                                    Executing some
> other handler in the middle of deciding what to do about the first
> exception doesn't seem the the obviously correct thing to do. But
> if we just keep unwinding the stack, the effect is to ignore
> exception 2 other than to execute some code of dubious value.

Could you elaborate on the obvious and dubious? After all, most exception
handler are there to put things in a state as correct as possible.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: stew@datalytics.com (Rob Stewart)
Date: 1996/09/10
Raw View
dak <pierreba@poster.cae.ca> wrote:
>Steve Clamage (clamage@taumet.Eng.Sun.COM) wrote:
>> In article e2i@netlab.cs.rpi.edu,  Max Polk <maxpolk@worldnet.att.net>
> writes:
>> >     Perhaps it is a bad idea ONLY because a bad rule exists that
>> >terminate() will be called immediately.
>>
>> It's easy to call it a bad rule without suggesting an alternative.
>> What do you suggest?
>>
>> Whatever you suggest as a replacement rule should be more usable and
>> have generally better results than just calling terminate(). Here are
>> a few things to consider.
>>
>> Suppose while unwinding the stack to handle exception 1, a
>> destructor exits via exception 2. What should happen?
>
>What about handling whichever exception handler is first encountered.
>At first sight it might seem inappropriate but:
>
>  - In the previous error handling scheme (either return value or
>    static error record) that is what happened. The first block of
>        code which handled any error was first executed, whatever the
>        order of error.
>
>  - There is not real hard reason why an error should be handled first
>    just because it happened first. In fact, executing whichever handler
>        comes first actually makes sense since the programmer chose in which
>        order to handle the exceptions.

Consider the following scenario. Your app tries to write to disk,
but the disk is full. Your code throws an exception to indicate
the out of space condition. Then, a dtor called as part of the
stack unwinding encounters a database error trying to commit some
dirty data. (This error is probably attributable to the same out
of space error, but assume it results in a different exception.)

Now assume the handler for the database problem is encountered
first. What do you do with the DB exception? Perhaps you notify
the user that you cannot write changes to the database. Maybe you
try to write them to a "pending" file. If you try the latter,
you'll encounter an out of space exception. But, you dutifully
handled the exception by telling the user you cannot cache the
changes for a later update.

At this point, you've finished handling the DB exception and
those it triggered. So, control returns to the code that first
tried to write to disk and it thinks all went well--it didn't
encounter an exception, did it? Is this desirable behavior? No.

>  - Innermost handler are ussually there to protect the rest of the
>    world about a specific exception. Passing over it because its
>        exception didn't come first might not be appropriate. Some very
>        important code might be skipped.

But some very important code can be skipped by not handling the
first exception.

You can't do both, so you call terminate()!

Robert Stewart  | My opinions are usually my own.
Datalytics, Inc. | stew@datalytics.com
   | http://www.datalytics.com


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]