Boost logo

Boost :

From: Beman Dawes (beman_at_[hidden])
Date: 1999-08-30 12:30:04


In private email, Kevlin Henney points out that use of assert() in
boost headers violates the ODR (one-definition rule). Another
problem with assert(), of course, is that it is a macro and thus
doesn't respect scope rules.

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?

--Beman

PS: This codes works as expected under Metrowerks CodeWarrior, fails
to compiler under Microsoft VC++, and hasn't been tried on any other
compilers.

-------------- snip here -----------------

#include <stdexcept>
#include <cstdlib>
using namespace std;

namespace // in a real header, this would be namespace boost
{
        // this form always throws on !condition
        inline void assertion( bool condition )
          { if (!condition) throw logic_error( "assertion failed" ); }
        
        // this form only throws on !condition if Activate == true
        template<bool Activate>
        inline void assertion( bool condition ) // #2
          { if (!condition) throw logic_error( "assertion failed" ); }
        
        // this specialization causes optimizers to generate no code
        template<> inline void assertion<false>( bool ) {}
}

// 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
}

// purpose of main() is to generate code for viewing, not actual
execution.

int main() {

  int i = rand(); // use rand() to fool optimizers

  assertion( i < 1 ); // always check
  assertion<DEBUG_ONLY>( i < 2 ); // check only if DEBUG_ONLY is
false

  return 0;
  }


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