|
Boost : |
From: Hendrik Schober (boost_at_[hidden])
Date: 2001-11-14 06:18:09
<Msk_at_[hidden]> wrote:
> [...]
> In boost.assert, perhaps it would be useful to factor out
> the "how to format/log a string" part separately from
> the "should we assert() or throw or die" part. Then
> any code developed to do nice formatting could be
> used in other places as well as for assert.
> [...]
> if( num_widgets > max_widgets )
> {
> throw logic_error(
> BOOST_ERROR_MESSAGE << "num_widgets = " <<
> num_widgets << " is greater than maxwidgets = " <<
> max_widgets );
> }
> [...]
Once the "formatting a string"-problem is attacked,
I'd rather have it solving the "do the same with
respect to i18", in order to make it more usefull
in general. The problem with other languages is
that it might change word and argument orderings.
With the above that's hard to do.
We use a scheme which allows to do this:
"A message with @(arg #1) and @(another arg)."
You pass two arguments, one is named "arg #1", the
other "another arg". We use this for exceptions
//NotFound: "@(type) @(key) was not found"
throw XFileSpecError( ORIGIN_HERE, CMessage(NotFound)
+ buildNamedParameter("type","folder")
+ buildNamedParameter("key",filespec) );
as well as for logging:
LogMsg( ORIGIN_HERE,
"Object allocated @@@(this), about to call @(foo())...",
ERROR_PAR(this)+ERROR_PAR(foo()) );
Since all our software is event driven (and we don't
write software where failure is disastrous), we
decided not to abort on failed assertions. If, e.g.,
printing a document failed due to a bug, why not let
the users try to save their work? (Users generally do
not save often enough! ;^> ) So our assertions throw
an exception:
#if !defined(ERROR_NO_ASSERTION) // disregard 'NDEBUG'
# define ERROR_ASSERTION
#endif // !defined(ERROR_NO_ASSERTION)
#define ASSERT(expr) Detail::excAssert_(ORIGIN_HERE,expr,#expr)
#define ASSERT_PAR(expr,par) Detail::excAssert_(ORIGIN_HERE,expr,#expr,par)
namespace Detail {
// ...
template< class T >
inline void excAssert_( ORIGIN_SIGN, const T& tExpr,
const char* const szExpr, const CNamedParameter& np )
{
#if defined(ERROR_ASSERTION)
if( !tExpr )
throw XAssertionFailed( ORIGIN_PASS, CAssertionMsg(ORIGIN_PASS,szExpr), np );
#endif //defined(ERROR_ASSERTION)
}
} //namespace Detail
The problem with what we have is, in a performance
critical application most of it probably won't do very
good. For us it has been performing good enough, so we
never invested the time to improve it.
> - Michael Kenniston
Schobi
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk