Boost logo

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