Boost logo

Boost :

From: Valentin Bonnard (Bonnard.V_at_[hidden])
Date: 1999-08-30 13:09:35


Beman Dawes wrote:

> In private email, Kevlin Henney points out that use of assert() in
> boost headers violates the ODR

It's not boost, it's the user who uses boost ! ;-)

> Another
> problem with assert(), of course, is that it is a macro and thus
> doesn't respect scope rules.

assert (like errno, etc) are standards macros so even if boost
provides an alternative, people will still have to consider these
names reserved.

> Bjarne Stroustrup, in C++ Programming Language, 3rd, page 750, also
> points out assert()'s lack of granularity, and further suggests it
> should throw on failure.
>
> Bjarne suggests template based alternatives.
>
> I tried (see below) a somewhat different formulation from his, in
> order to 1) more surely avoid generating code when the assertion
> isn't active, and 2) clearly separate the argument specifying whether
> the assertion is active or not from the argument specifying the
> logical condition which much be met.
>
> Do others think that some such template base assertion approach is
> worth developing for boost? Has anyone else tried to develop
> assert() replacements?

If the goal is not to break the ODR, than there should be
one extern const bool debug_mode = value.

> // this form always throws on !condition
> inline void assertion( bool condition )
> { if (!condition) throw logic_error( "assertion failed" ); }

Not using macros, you loose __FILE__ and __LINE__.

> // boost might want to provide something like this
> namespace // unnamed namespace avoids ODR violation
> {
> #ifdef NDEBUG
> const bool DEBUG_ONLY = false;
> #else
> const bool DEBUG_ONLY = true;
> #endif

constants have internal linkage in C++

I propose the following:

// precondition: that debug_mode is defined
#define BOOST_ASSERT_THROW(condition) \
  (debug_mode ? boost::Utils::assert_throw(condition, __LINE__,
__FILE__) : 0)

namespace boost {
namespace Utils {
  struct AssertFailure : std::logic_error {
     AssertFailure (long line, const char* file);
  ...
  };

  inline void assert_throw (bool c, long line, const char* file)
  { if (c) throw AssertFailure (line, file); }
}
using namespace Utils;
}

-- 
Valentin Bonnard

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