Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2001-04-12 08:30:38


----- Original Message -----
From: "Peter Dimov" <pdimov_at_[hidden]>

> The paper is good, but "Yes, if you want and can afford stack unwinding"
is
> only one of the possible answers to "Should I throw an exception in this
> situation."
>
> I'd also add these as possible answers:
>
> "Yes, if this simplifies client code considerably"; (eliminated return
code
> checks)

I think this is technically the same answer. If the caller can avoid
checking return codes, then he's willing to have the stack unwind... at
least to the next enclosing catch block, which, to be convenient, must
generally begin some statements after the calling statement, if not in a
different function. Still, I think it is clearer to say the above than to
not say it; when I get a chance I'll make that addition.

> "Yes, if you have to abort a long chain of operations";

Hmm...
    op1();
    op2();
    op3();
    if (!op4()) return aborted;
    op5();
    op6();
    return success;

You must have had something else in mind...

> "Yes, if there is no other alternative". (constructor failures)

Good point.

> IOW, to apply this to the "not found" situation above:
>
> for(; first != last; ++first)
> {
> if(found(*first)) f(*first); else g(*first);
> }
>
> -- an exception is not appropriate, the 'not found' situation has O(n)
> potential.
>
> for(; first != last; ++first)
> {
> if(!found(*first)) f(*first); else break;
> }
>
> -- an exception may be appropriate, the 'not found' situation has O(1)
> potential.

I guess I don't understand how you would use an exception here. Do you mean
it would make sense to throw in the break case, when the found returns true?
Or maybe you mean that it makes sense to throw from f()?

> std::for_each(first, last, call_f_if_found);
>
> -- an exception is the only way to 'break' from for_each.

True, but in this case for_each is simple enough that an algorithm not
supplied by the standard might be appropriate (e.g. while_predicate). A
better example might be a relatively expensive and complicated graph
algorithm with many levels of nested calls and components. An exception may
be the only way to stop processing in this case - we have this situation
with Boost.Graph. When the inputs get large, it may even be more efficient
to use an exception to stop processing than it is to check return codes
repeatedly.

> About using 'assert' in a library: there's also the ODR problem to worry
> about.

True, but AFAICT nearly all modern code has some preprocessor-dependent
definitions somewhere in header files, making this problem a fact of life.

-Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk