|
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