David Abrahams wrote:
Sometimes I'm guilty of writing far too much detail, and I've learned to try to keep it simple and direct, at least "most of the time", and then I always get hit with a complaint that I didn't cover all the bases. You really can't win, can you? ;-)Dave Butenhof <David.Butenhof@xxxxxx> writes:The real issue isn't so much catching without a re-throw, but catching and dropping arbitrary exceptions. If you don't claim to know how to finalize a bad_alloc error, what business do you have catching it? (And since catch(...) is anonymous, even if you could handle it you can't identify it.) I'm not convinced there's any rational excuse for finalizing bad_alloc unless you know how to free up some memory to "cure" the problem that caused it. (Nor would there be any particular benefit.) If you can't deal with it, you need to let it propagate to someone who can; or to terminate the process.[...] If there was an exception I couldn't recognize, it would always be better to say "something I can't identify went wrong; you might want to save under a different name" than to allow the program to terminate suddenly, and *definitely* drop the document's data on the floor. Of course, I never saw an exception I couldn't identify, but termination is not always the right answer. Another real-life example someone once gave me was that of a stage lighting controller. It was always better to plow ahead and hope the issue wasn't serious than to have the stage go suddenly black. There are surely places where finalizing a catch(...) is wrong, but there's no blanket rule that applies to all applications.
Yes, of course there are exceptions; mostly in outer level control structures, though, not in the inner depths of a library. I've always argued it should be POSSIBLE to finalize any exception, including cancel; and in fact that's one of the major reasons I've always felt that cancel should BE an exception, since the syntax is already there.
The issue we've been discussing is not whether there are exceptions, or where they are, but rather how to "warp" our basic theoretically clean model to deal with the reality that C++ libraries (including STL) are rife with arbitrary catch(...) blocks that stop exceptions; often with no really supportable reason except that it seemed convenient at the time. Most of this code should NOT be continuing when an exception occurs they can't directly finalize; they should be passing it on to someone who can. That might be some outer scope that really understands the exception, or it might be some "failsafe catchall" in the main program loop like you're describing. We can keep this inner code from seeing cancel, we can keep it from catching it, we can re-raise cancel after the catch, or we can just let it trash the cancel and force the code to be fixed if the user really wants that thread to be cancellable while in the library.
Note that my (hypothetical, simply for the purposes of abstract consideration) proposal for dynamic cancel scoping based (at least partly) on exception constructs, would result in cancel being completely disabled in any thread run by your "recover at all costs" main loop; because the entire call tree would be inside a catch(...) scope. The question is whether that's bad. The thread presumably was never cancellable before, unless it was designed for a POSIX implementation where C++ and POSIX cancel interoperate reasonably well (which doesn't leave many implementations). So it wouldn't be cancellable in the new "c++-pthreads" model, either, without some code changes. That doesn't sound like a big deal. If you WANT it to be cancellable, you could enable it by simply adding an explicit catch for the cancel exception to that try block. That's trivial compared to the work required just to check whether the rest of the threads' call stacks are cancel-safe.
-- /--------------------[ David.Butenhof@xxxxxx ]--------------------\ | Hewlett-Packard Company Tru64 UNIX & VMS Thread Architect | | My book: http://www.awl.com/cseng/titles/0-201-63392-2/ | \----[ http://homepage.mac.com/dbutenhof/Threads/Threads.html ]---/