|
Boost : |
From: E. Gladyshev (egladysh_at_[hidden])
Date: 2003-11-04 04:10:38
--- David Abrahams <dave_at_[hidden]> wrote:
[...]
> > It catches all exceptions, so there is nothing safe
> > after that. I might be missing something but
> > I think that it is creates a very bad impression
> > that after you put catch(...), it is safe
> > to use the object.
>
> Show me any C++ code you think is safe, and I will show you that your
> claim of safety relies on all the same conditions.
I think that the following code is much safer.
The first precondition is that you have to know what
exceptions a "correct" implementation of a class
can possibly generate. Let's assume that
that the correct method, my_type::f() can generate
only one exception, out_of_memory and my_type
provides basic guarantees.
Then the safer code is
my_type *p = new my_type
try
{
p->f();
}
catch( out_of_memory ) //it is safe to use 'p'
{
delete p;
}
catch( ... ) //nothing is safe, don't use 'p'
{
exit(); //or throw; or while(1) {} just try to stop the execution here by any means
}
>
> > To fix the above code you need list all
> > known exception types before catch(...).
>
> Why do you think so?
See the above, when you do catch(...), you are cathing
all exception including the one that can be caused
by incorrect program.
>
> > In catch(...), you just better do nothing.
>
> Nothing *is* done "in catch(...)"
I think you know what I meant. You cannot use the object after catch(...)
as in your example.
>
> > template <class X>
> > void print_random_sequence()
> > {
> > std::vector<X> v(10); // A vector of 10 items
> > try {
> > // Provides only the basic guarantee
> > v.insert( v.begin(), X() );
> > }
> > catch( out_of_memory ) {}// ignore any exceptions above
> > catch( bad_mood ) {} // ignore any exceptions above
> > catch(...)
> > { //nothing is safe, run!
> > }
> > // print the vector's contents
> > std::cout "(" << v.size() << ") ";
> > std::copy( v.begin(), v.end(),
> > std::ostream_iterator<X>( std::cout, " " ) );
> > }
>
> That does exactly the same thing as my version. Maybe you should
> check out Herb Sutter's "[More] Exceptional C++" books. They discuss
> many of these issues in a tutorial fashion.
Sorry, I meant
catch(...)
{ //nothing is safe, run!
return; //throw; exit()
}
The bottom line is that you cannot use 'v' anymore.
[...]
>
> I can think of lots of comebacks for that one,
Sorry, I was just kidding (it is not the first missle joke on this thread). :)
> but instead let me
> suggest that you make a good, careful study of the issues and consider
> the full context of my article before you decide you know how to
> handle exceptions more safely than the rest of us.
What do you mean by "rest of us"?
Thanks to this thread, I think that I can define
safer exception handling techniques for myself.
1. If your method breaks an invariant internally and calls
an outside method, make sure that you know all exceptions that
a correct implementation of the outside method can generate.
Catch the know exceptions *explicitly* and restore invariants.
See the next item on what to do in catch(...)
2. If you call a method f() that provides basic guarantees,
make sure to *explicitly* catch all exceptions that correct
f() can possibly generate. It is possibly safe to continue
the execution after a know exception.
In the catch(...) block, assume that nothing is safe,
use h/w interlocks or other system means to stop
the execution immediately.
This is what I would do to keep the missle in place. :)
Eugene
__________________________________
Do you Yahoo!?
Protect your identity with Yahoo! Mail AddressGuard
http://antispam.yahoo.com/whatsnewfree
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk