Boost logo

Boost :

From: Michael Crawford (crawford_at_[hidden])
Date: 2005-11-12 03:30:26


libmdc is a set of utility and debugging classes that I expect would be
useful in most C++ programs. Mostly it consists of assertion
bottlenecks to help you eliminate pointer and memory bugs from your
programs. There will be more soon to help with class invariant and
design by contract assertions.

    libmdc - Mike Crawford's C++ Library
    http://www.goingware.com/libmdc/

It's also meant to make unit testing easier. It includes CPPUnit.mk and
CPPUnit.t.mk, sub-makefiles which ease building CPPUnit unit tests with
GNU make. My assertion_failed exception class includes a macro which
can be used by your own assertion macros to throw an exception upon
assertion failure. This enables one to use CPPUnit to test assertion
failures without aborting the tests. My mdc_assert can do this.

libmdc is Free Software, released under the Boost Software License.
It's my intention that when I'm finished writing it, I will submit it
for review for possible inclusion in Boost itself.

It is not nearly done yet, but this preview release is provided to
solicit comments. My question for you is, do you see any obvious
mistakes? How can I do better?

My valid_ptr template is a non-owning smart pointer that cannot be NULL.
  I'm also going to write a template I'll call checked_ptr that CAN be NULL.

valid_ptr uses and checked_ptr will use the legal_addr template which
reads the first byte addressed by any reference or non-NULL pointer.
Given an unmapped address, it causes an immediate crash, but probably
sooner and easier to debug than letting it snowball through your
program. Used with a memory debugger like valgrind, Purify or
Spotlight, you can find and fix bad memory references with ease. I have
used this technique before and while it's dead-simple, it is also very
powerful.

libmdc doesn't have proper documentation yet, but there is some in the
form of comments in the header files. The unit tests also serve as
sample code. The Makefile is extensively commented to show you how to
use CPPUnit.mk to build unit tests for your classes. CPPUnit.mk itself
contains complete documentation for its use.

I build unit tests the way John Lakos advises in Large Scale C++
Software Design: I only link in the class under direct test, and those
sources which are absolutely required to make the test link. For
reasons that Lakos eloquently explains, I DON'T link in my entire
project, as I think is the more common practice.

To keep this manageable, I need a separate makefile to build each unit
test. CPPUnit.t.mk encapsulates what is common to building all unit
tests, so that the *.t.mk unit test makefiles need have little more in
them than a list of the dependencies.

Following is from the README file:

libmdc is a set of utility and debugging classes likely to be useful
in many C++ projects. Everything is in the namespace mdc. There aren't
any dependencies on anything outside this directory except for the
standard C++ library, Boost and CPPUnit for the unit tests.

You will need to build and install the Boost C++ library and the
CPPUnit automated test framework before you can build this code:

http://www.boost.org/
http://cppunit.sourceforge.net/cppunit-wiki/

To build the executables, just take "make". To build and then
run the tests (both unit tests and other tests) type "make test".
There is no "make install" yet.

The library so far contains:

CPPUnit.mk, CPPUnit.t.mk

Sub-makefiles to make it a lot easier to build CPPUnit unit tests
with GNU make.

valid_ptr

non-owning smart pointer; forbids NULL pointers.

legal_addr

pointer debugging, best used with valgrind, purify or spotlight.

null_ptr_checker

throws an exception when given a NULL pointer.

null_ptr_exception

The exception it throws.

mdc_assert

Debugging macro, aborts or drops into debugger when its
assertion evaluates to false. This is used instead
of the standard library assert so it may be separately
disabled. Assertions are enabled by default, for
release builds, #define MDC_NO_ASSERT 1 or
pass -DMDC_NO_ASSERT=1 to the C++ compiler.

assertion_failed

meant for testing failed assertions in unit tests.
You can configure mdc_assert to throw this exception with
#define MDC_ASSERTION_EXCEPTION 1

errno_exception

on POSIX systems, throw this exception after a system
call fails so that the catcher can print a good error message

string_invariant

The beginning of class invariant assertions for the Standard Library

valid_ptr is a smart pointer like auto_ptr, scoped_ptr or
shared_ptr, except that it doesn't take ownership of the pointer
it holds. Instead, construct a valid_ptr from a pointer that
your class or function is given to use, but not manage. It will
throw a null_ptr_exception and optionally assert if the pointer
is ever NULL.

Besides validating the pointer it is given, valid_ptrs serve as
documentation to help make ownership issues clear. Using valid_ptrs
as class member variables indicates that the pointers are used by,
but not owned by the class. Similarly, declaring them as function
parameters indicates that the pointers passed in cannot be NULL, and
again that ownership of them is not captured by the receiving function.

Use either scoped_ptr, shared_ptr or auto_ptr for situations where
pointer ownership is required. Which one to use depends on the
requirements of each situation.

There is sample code too: the tests. There are unit tests
for most of the classes that use the CPPUnit automated test
framework.

There is also a simple program called HeaderCheck that I used
to debug some problems with my header files while I was first
writing valid_ptr.h. CPPUnit does some extreme macro and
template magic, so HeaderCheck serves as a simpler testbed.

Enjoy! -- Mike

-- 
Michael D. Crawford
GoingWare Inc. - Expert Software Development and Consulting
http://www.goingware.com/
crawford_at_[hidden]
    Tilting at Windmills for a Better Tomorrow.

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