This library implements contract
programming (a.k.a., Design by Contract or DbC) [1] for the C++ programming language. All contract programming features
are supported by this library: Subcontracting, class invariants (also for static
and volatile member functions), postconditions (with old and return values),
preconditions, customizable actions on assertion failure (e.g., terminate the
program or throw exceptions), optional compilation of assertions, disable assertions
while already checking other assertions (to avoid infinite recursion), and more
(see Feature
Summary).

Contract programming allows to specify preconditions, postconditions, and class
invariants that are automatically checked when functions are executed at run-time.
These conditions assert program specifications within the source code itself
allowing to find bugs more quickly during testing, making the code self-documenting,
and increasing overall software quality (see Contract
Programming Overview).

For example, consider the following function inc
that increments its argument x
by 1 and let's write its contract
using code comments (see introduction_comments.cpp):

The precondition states that at function entry the argument x
must be strictly smaller than the maximum allowable value of its type (so it
can be incremented by 1 without
overflowing). The postcondition states that at function exit the argument
x must be incremented by 1 with respect to the old value
that x had before executing
the function (indicated here by oldof(x)).
Note that postconditions shall be checked only when the execution of the function
body did not throw an exception.

#include<boost/contract.hpp>voidinc(int&x){boost::contract::old_ptr<int>old_x=BOOST_CONTRACT_OLDOF(x);// Old value.boost::contract::checkc=boost::contract::function().precondition([&]{BOOST_CONTRACT_ASSERT(x<std::numeric_limits<int>::max());// Line 17.}).postcondition([&]{BOOST_CONTRACT_ASSERT(x==*old_x+1);// Line 20.});++x;// Function body.}

For example, if there is a bug in the code calling inc
so that the function is called with x
equal to std::numeric_limits<int>::max() then the program will terminate with an error
message similar to the following (and it will be evident that the bug is in
the calling code):

Instead, if there is a bug in the implementation of inc
so that x is not incremented
by 1 after the execution of the
function body then the program will terminate with an error message similar
to the following (and it will be evident that the bug is in inc
body): [2]

By default, when an assertion fails this library prints an error message such
the ones above to the standard error std::cerr and
terminates the program calling std::terminate
(this behaviour can be customized to take any user-specified action including
throwing exceptions, see Throw
on Failures). Note that the error messages printed by this library contain
all the information necessary to easily and uniquely identify the point in
the code at which contract assertions fail. [3]

Note

C++11 lambda functions are necessary to use this library without manually
writing a significant amount of boiler-plate code to program the functors
that assert the contracts (see No
Lambda Functions). That said, this library implementation does not
use C++11 features and should work on most modern C++ compilers (see Getting Started).

In addition to contracts for non-member functions as shown the in the example
above, this library allows to program contracts for constructors, destructors,
and member functions. These can check class invariants and can also subcontract
inheriting and extending contracts from base classes (see introduction_public.cpp
and Public
Function Overrides): [4]

template<typenameT>classvector#defineBASESpublicpushable<T>:BASES{public:typedefBOOST_CONTRACT_BASE_TYPES(BASES)base_types;// For subcontracting.#undefBASESvoidinvariant()const{// Checked in AND with base class invariants.BOOST_CONTRACT_ASSERT(size()<=capacity());}virtualvoidpush_back(Tconst&value,boost::contract::virtual_*v=0)/* override */{// For virtuals.boost::contract::old_ptr<unsigned>old_size=BOOST_CONTRACT_OLDOF(v,size());// Old values for virtuals.boost::contract::checkc=boost::contract::public_function<// For overrides.override_push_back>(v,&vector::push_back,this,value).precondition([&]{// Checked in OR with base preconditions.BOOST_CONTRACT_ASSERT(size()<max_size());}).postcondition([&]{// Checked in AND with base postconditions.BOOST_CONTRACT_ASSERT(size()==*old_size+1);});vect_.push_back(value);}BOOST_CONTRACT_OVERRIDE(push_back)// Define `override_push_back` above.// Could program contracts for those as well.unsignedsize()const{returnvect_.size();}unsignedmax_size()const{returnvect_.max_size();}unsignedcapacity()const{returnvect_.capacity();}private:std::vector<T>vect_;};

The authors of this library advocate for contracts to be added to the core
language. Adding contract programming to the C++ standard has a number of advantages
over any library implementation (shorter and more concise syntax to program
contracts, specify contracts in declarations instead of definitions, enforce
contract constant-correctness, expected faster compile- and run-time, vendors
could develop static analysis tools to recognize and check contracts statically
when possible, compiler optimizations could be improved based on contract conditions,
etc.).

Unfortunately, detailed and complete proposals to add contracts to the C++
standard such as [N1962] were rejected
by the C++ standard committee and it is not clear if the current proposal for
adding contracts to C++ [P0380] will actually
be accepted by the standard. [5] In any case, at least for now [P0380]
only supports pre- and postconditions while missing basic features such as
class invariants and old values in postconditions, not to mention the lack
of more advanced features like subcontracting. All these features are instead
supported by this library (see Feature
Summary for a detailed comparison between the features supported by
this library and the ones listed in different contract programming proposals,
see Bibliography for a list
of references considered during the design and implementation of this library,
including the vast majority of contract programming proposals submitted to
the C++ standard committee).

[1]
Design by Contract (DbC) is a registered trademark of the Eiffel Software company
and it was first introduced by the Eiffel programming language (see [Meyer97]).

[2]
In this example the function body is composed of a single trivial instruction
++x
so it easy to check by visual inspection that it does not contain any bug
and it will always increment x
by 1 thus the function postcondition
will never fail. In real code, function bodies are rarely this simple and
can hide bugs which makes checking postconditions useful.

[3] Rationale: The assertion failure message
printed by this library follows a format similar to the message printed by
Clang when the C-style assert
macro fails.

[4]
The pushable base class is
used in this example just to show subcontracting, it is somewhat arbitrary
and it will likely not appear in real code.

[5]
The authors find attractive the syntax that uses C++11 attributes [[...]] to specify contracts as indicated
in [P0380].