Boost logo

Boost :

From: Kevin S. Van Horn (Kevin.VanHorn_at_[hidden])
Date: 2002-11-11 09:49:45

It's been six days since I posted this, without a single response, so I'm
going to try again. Based on earlier discussions, I thought there might
be some interest in this. Does anyone have any problems with the proposed
interface? Should I turn this into a formal proposal for submission to
Boost? Peter, how does this compare with the changes to
<boost/assert.hpp> you were planning to do / are doing?


I've taken the existing (but not documented for external use)
<boost/assert.hpp> that Peter Dimov wrote, and have modified/extended it
to have the facilities that I would like to see. You can download my code
from (gzipped tar format)
or (ZIP format).

These packages include documentation and fairly extensive regression tests.
Unfortunately, the tests are not fully portable, as they rely on shell scripts.
I haven't yet taken a look at how the existing Boost regression tests
manage portability; some issues are the need to run a program and test its
output and exit status.

Here's a very rough cut at the documentation:


Header file: <boost/assert.hpp>

Purpose: to provide flexible alternative to assert() that allows the
applications programmer to customize what happens when an assertion is found
false, while making it easy to specify the most commonly desired behaviors.
This facility is intended to be lightweight, with minimal dependencies on
the rest of Boost or parts of the Standard Library that tend to bloat the size
of executables.

Definition: A static string is a value implicitly convertible to a const
char * value that is either null or points to a null-terminated char array
that remains valid and unchanged for the lifetime of the program. String
literals and pointers to static const char arrays are examples.

Components provided for users:

- Class failed_assertion.

  - failed_assertion(char const * expr, char const * msg, char const * fct,
                     char const * file, unsigned line);

    - PURPOSE: Indicates that an assertion with textual representation expr
    failed, at the indicated line number and file, within function fct. The
    string msg is additional information explaining the error.
    - REQUIRES: expr, msg, fct, and file are static strings.
    - REQUIRES: expr, fct, and file are non-null. (msg may be null.)

  - copy ctor, copy assign, public dtor also provided.

  - Public data members
    char const * assert_expression;
    char const * message;
    char const * function_name;
    char const * file_name;
    unsigned line_number;

- Type assert_handler_t. This is a typedef for
    bool (*)(char const * expr, char const * msg, char const * func,
             char const * file, unsigned line, bool throw_exception)
  - expr is the text of the failed assertion.
  - msg is any additional text explaining the error.
  - func, file, and line are the function, file name, and line number at
    which the error occurred.
  - throw_exception indicates whether the user has indicated a preference
    for an exception to be thrown when an assertion fails.

- Function
    assert_handler_t set_assert_handler(assert_handler_t h).
  Returns the old assert handler and sets h as the new assert handler.
  Initially there is no assert handler (null function pointer). See
  BOOST_ASSERT_MSG below for how the assert handler is used.

  - Value is true if BOOST_ASSERT_THROWS is defined, false otherwise.

- Macro BOOST_ASSERT_MSG(e, msg).
  - If BOOST_DEBUG is not defined, this is a no-op.
  - Otherwise, if user has already provided a definition for BOOST_ASSERT_MSG,
    the definition is left unchanged.
  - Otherwise,
    - If there is an assert handler h, calls h with BOOST_ASSERT_THROW_FLAG as
      the throw_exception argument.
    - If there is no assert handler, or if it returns true, then
      - if BOOST_ASSERT_THROWS is defined, throw a failed_assertion exception;
      - otherwise, print an error message to stderr and abort.
  - msg is a static string that provides additional explanation of the error;
    it may be null.
  - e may be evaluated more than once.

  - If BOOST_DEBUG is not defined, this is a no-op
  - Otherwise, if user has already provided a definition for BOOST_ASSERT,
    the definition is left unchanged.
  - Otherwise, equivalent to BOOST_ASSERT_MSG(e, 0)

Symbols that may be defined by users:

- BOOST_DEBUG. If not defined, then BOOST_ASSERT(e) and BOOST_ASSERT_MSG(e,
  msg) are no-ops. This symbol is #undef'd if NDEBUG is defined.

- BOOST_ASSERT_MSG(e, msg). Users may provide their own definition of this
  macro, which will override the definition in <boost/assert.hpp>.

- BOOST_ASSERT(e). Users may provide their own definition of this macro,
  which will override the definition in <boost/assert.hpp>

- BOOST_ASSERT_THROWS. If defined, then the default behavior for
  BOOST_ASSERT(e) and BOOST_ASSERT_MSG(e, msg) is to throw an exception.
  Otherwise, the default behavior is to print an error message to stderr
  and abort.


- One goal is to keep the basic assert facilities lightweight, and not require
  a lot of additional facilities.

- Line numbers are unsigned, and not unsigned long, because the C++ Standard
  guarantees that unsigned values are at least 32 bits, which should provide
  sufficient line numbers for any source file.

- failed_assertion is not derived from std::logic_error because doing so
  would require use of std::string (and linking of its code) even for those
  projects that prefer to use a different string class.

- The data members of failed_assertion are public for the same reason that the
  data members of std::pair<A, B> are public: the entire purpose of the class
  is simply to report a tuple of values.

- fprintf is used to print error messages in order to avoid requiring the
  use of iostreams, which can considerably increase executable size.

Boost list run by bdawes at, gregod at, cpdaniel at, john at