Boost logo

Boost :

From: E. Gladyshev (egladysh_at_[hidden])
Date: 2003-11-03 22:37:45


--- David Abrahams <dave_at_[hidden]> wrote:
[...]
> Have you read the analysis section of
> http://www.boost.org/more/generic_exception_safety.html?

Sorry, my reply went to a wrong place. I revisited
your article more carefully. Nice job!
But I think it creates some very bad assumptions.

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(...) {} // ignore any exceptions above
    // print the vector's contents
    std::cout "(" << v.size() << ") ";
    std::copy( v.begin(), v.end(),
    std::ostream_iterator<X>( std::cout, " " ) );
}

Then we see the following statement!

"Since all we know about v after an exception is that it is valid,
the function is allowed to print any random sequence of Xs.3
It is ``safe'' in the sense that it is not allowed to crash,
but its output may be unpredictable."

I don't see anything safe in this example.
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.

To fix the above code you need list all
known exception types before catch(...).
In catch(...), you just better do nothing.

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, " " ) );
}

There is supposedly another real-life example in this article:

template <class T> // 1
void SearchableStack<T>::push(const T& t) // 2
{ // 3
    set<T>::iterator i = set_impl.insert(t); // 4
    try // 5
    { // 6
        list_impl.push_back(i); // 7
    } // 8
    catch(...) // 9
    { // 10
        set_impl.erase(i); // 11
        throw; // 12
    } // 13
}

It sounds great in theory but if you use this
technique, in practice, on real h/w and real OS,
you'll make a false assumption that you are safe.
This is how we can get the missle fired and start
the next war. :)

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