|
Boost : |
From: Jesse Jones (jesjones_at_[hidden])
Date: 2001-03-18 06:24:27
>At 10:31 PM 3/17/2001, David Abrahams wrote:
>
> >Moreover, I am not at all convinced it is appropriate for our libraries
>to
> >attempt to check for client abuse. If and where we /do/ decide it is
> >appropriate, I agree with the idea of using configurable response
> >strategies. I also believe it is usually best to put these checks in a
> >separate layer on top of the base implementation, rather than trying to
> >weave them into the release code.
>
>Sometimes assert() and only assert() is clearly the Right Way.
>
>Sometimes throwing an exception, and only that, is clearly the Right Way.
>
>But it sounds like what we are talking about here are cases where neither
>one of those is clearly the Right Way.
In general I think it is possible to draw a distinction between errors
you should throw for and errors you should assert for. The case that
spawned this discussion is unusual in that there was concern that it was
timing sensitive so you could never be completely sure that it was
exercised enough in debug builds.
>So perhaps we need a BOOST_ASSERT(), which has at least three behaviors
>(determined by what preprocessor symbols are defined) when the predicate
>fails:
>
> * classic assert() with -NDEBUG not defined.
>
> * classic assert() with -NDEBUG defined.
>
> * throw logic_error (with file/line info?).
>
> * [possibly?] call some user or system function (with file/line info?).
I think this is a good idea in any case. The C assert is plainly
inaequate as is evident by how often people write replacements. Something
this critical really belongs in a library like Boost.
>Note that the use of BOOST_ASSERT() would be part of the function's
>interface (rather than just QOI) because user code may rely on some of the
>behavior choices.
I'm not sure this is wise. For example, this suggests that a function
documents that it is using BOOST_ASSERT to validate pre-conditions. But
pre-conditions can be arbitrarily complex so it's awfully difficult for
clients to assume that a function either works or throws unless you're
willing to pay a horrendous performance hit.
The other problem is the ripple effect: if a commonly used function is
re-written to use BOOST_ASSERT the documentation of every client of that
function has to be updated.
I still think it's better to try and partition errors into programmer and
system errors and handle one with assert and one with throw. Throwing is
part of the documentation. Programmer errors result in undefined
behavior, but a quality implementation will use asserts for as many of
these as possible and let clients modify the behavior of the assert.
-- Jesse
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk