1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Chapter 1. Boost.Contract 1.0.0</title> 5<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="index.html" title="Chapter 1. Boost.Contract 1.0.0"> 8<link rel="next" href="boost_contract/full_table_of_contents.html" title="Full Table of Contents"> 9</head> 10<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 11<table cellpadding="2" width="100%"><tr> 12<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td> 13<td align="center"><a href="../../../../index.html">Home</a></td> 14<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td> 15<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 16<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 17<td align="center"><a href="../../../../more/index.htm">More</a></td> 18</tr></table> 19<hr> 20<div class="spirit-nav"><a accesskey="n" href="boost_contract/full_table_of_contents.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div> 21<div class="chapter"> 22<div class="titlepage"><div> 23<div><h2 class="title"> 24<a name="boost_contract"></a>Chapter 1. Boost.Contract 1.0.0</h2></div> 25<div><div class="author"><h3 class="author"> 26<span class="firstname">Lorenzo</span> <span class="surname">Caminiti <code class="email"><<a class="email" href="mailto:lorcaminiti@gmail.com">lorcaminiti@gmail.com</a>></code></span> 27</h3></div></div> 28<div><p class="copyright">Copyright © 2008-2019 Lorenzo Caminiti</p></div> 29<div><div class="legalnotice"> 30<a name="boost_contract.legal"></a><p> 31 Distributed under the Boost Software License, Version 1.0 (see accompanying 32 file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) 33 </p> 34</div></div> 35</div></div> 36<div class="toc"> 37<p><b>Table of Contents</b></p> 38<dl class="toc"> 39<dt><span class="section"><a href="index.html#boost_contract.introduction">Introduction</a></span></dt> 40<dt><span class="section"><a href="boost_contract/full_table_of_contents.html">Full Table of Contents</a></span></dt> 41<dt><span class="section"><a href="boost_contract/getting_started.html">Getting Started</a></span></dt> 42<dt><span class="section"><a href="boost_contract/contract_programming_overview.html">Contract 43 Programming Overview</a></span></dt> 44<dt><span class="section"><a href="boost_contract/tutorial.html">Tutorial</a></span></dt> 45<dt><span class="section"><a href="boost_contract/advanced.html">Advanced</a></span></dt> 46<dt><span class="section"><a href="boost_contract/extras.html">Extras</a></span></dt> 47<dt><span class="section"><a href="boost_contract/examples.html">Examples</a></span></dt> 48<dt><span class="section"><a href="reference.html">Reference</a></span></dt> 49<dt><span class="section"><a href="boost_contract/release_notes.html">Release Notes</a></span></dt> 50<dt><span class="section"><a href="boost_contract/bibliography.html">Bibliography</a></span></dt> 51<dt><span class="section"><a href="boost_contract/acknowledgments.html">Acknowledgments</a></span></dt> 52</dl> 53</div> 54<div class="blockquote"><blockquote class="blockquote"><p> 55 <span class="emphasis"><em><span class="quote">“<span class="quote">Our field needs more formality, but the profession has not 56 realized it yet.</span>”</span></em></span> 57 </p></blockquote></div> 58<div class="blockquote"><blockquote class="blockquote"><p> 59 <span class="emphasis"><em>-- Bertrand Meyer (see <a class="link" href="boost_contract/bibliography.html#Meyer97_anchor">[Meyer97]</a> 60 page 400)</em></span> 61 </p></blockquote></div> 62<p> 63 This library implements <a href="http://en.wikipedia.org/wiki/Design_by_contract" target="_top">contract 64 programming</a> (a.k.a., Design by Contract or DbC) <a href="#ftn.boost_contract.f0" class="footnote" name="boost_contract.f0"><sup class="footnote">[1]</sup></a> for the C++ programming language. All contract programming features 65 are supported by this library: Subcontracting, class invariants (also for static 66 and volatile member functions), postconditions (with old and return values), 67 preconditions, customizable actions on assertion failure (e.g., terminate the 68 program or throw exceptions), optional compilation of assertions, disable assertions 69 while already checking other assertions (to avoid infinite recursion), and more 70 (see <a class="link" href="boost_contract/contract_programming_overview.html#boost_contract.contract_programming_overview.feature_summary" title="Feature Summary">Feature 71 Summary</a>). 72 </p> 73<div class="section"> 74<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 75<a name="boost_contract.introduction"></a><a class="link" href="index.html#boost_contract.introduction" title="Introduction">Introduction</a> 76</h2></div></div></div> 77<p> 78 Contract programming allows to specify preconditions, postconditions, and class 79 invariants that are automatically checked when functions are executed at run-time. 80 These conditions assert program specifications within the source code itself 81 allowing to find bugs more quickly during testing, making the code self-documenting, 82 and increasing overall software quality (see <a class="link" href="boost_contract/contract_programming_overview.html" title="Contract Programming Overview">Contract 83 Programming Overview</a>). 84 </p> 85<p> 86 For example, consider the following function <code class="computeroutput"><span class="identifier">inc</span></code> 87 that increments its argument <code class="computeroutput"><span class="identifier">x</span></code> 88 by <code class="computeroutput"><span class="number">1</span></code> and let's write its contract 89 using code comments (see <a href="../../example/features/introduction_comments.cpp" target="_top"><code class="literal">introduction_comments.cpp</code></a>): 90 </p> 91<p> 92</p> 93<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> 94 <span class="comment">// Precondition: x < std::numeric_limit<int>::max()</span> 95 <span class="comment">// Postcondition: x == oldof(x) + 1</span> 96<span class="special">{</span> 97 <span class="special">++</span><span class="identifier">x</span><span class="special">;</span> <span class="comment">// Function body.</span> 98<span class="special">}</span> 99</pre> 100<p> 101 </p> 102<p> 103 The precondition states that at function entry the argument <code class="computeroutput"><span class="identifier">x</span></code> 104 must be strictly smaller than the maximum allowable value of its type (so it 105 can be incremented by <code class="computeroutput"><span class="number">1</span></code> without 106 overflowing). The postcondition states that at function exit the argument 107 <code class="computeroutput"><span class="identifier">x</span></code> must be incremented by <code class="computeroutput"><span class="number">1</span></code> with respect to the <span class="emphasis"><em>old value</em></span> 108 that <code class="computeroutput"><span class="identifier">x</span></code> had before executing 109 the function (indicated here by <code class="literal"><span class="emphasis"><em>oldof</em></span></code><code class="computeroutput"><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>). 110 Note that postconditions shall be checked only when the execution of the function 111 body does not throw an exception. 112 </p> 113<p> 114 Now let's program this function and its contract using this library (see <a href="../../example/features/introduction.cpp" target="_top"><code class="literal">introduction.cpp</code></a> 115 and <a class="link" href="boost_contract/tutorial.html#boost_contract.tutorial.non_member_functions" title="Non-Member Functions">Non-Member 116 Functions</a>): 117 </p> 118<p> 119</p> 120<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">contract</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 121 122<span class="keyword">void</span> <span class="identifier">inc</span><span class="special">(</span><span class="keyword">int</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> 123 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">old_x</span> <span class="special">=</span> <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="comment">// Old value.</span> 124 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">function</span><span class="special">()</span> 125 <span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> 126 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">max</span><span class="special">());</span> <span class="comment">// Line 17.</span> 127 <span class="special">})</span> 128 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> 129 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_x</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// Line 20.</span> 130 <span class="special">})</span> 131 <span class="special">;</span> 132 133 <span class="special">++</span><span class="identifier">x</span><span class="special">;</span> <span class="comment">// Function body.</span> 134<span class="special">}</span> 135</pre> 136<p> 137 </p> 138<p> 139 When the above function <code class="computeroutput"><span class="identifier">inc</span></code> 140 is called, this library will: 141 </p> 142<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 143<li class="listitem"> 144 First, execute the functor passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">precondition</span><span class="special">(...)</span></code> 145 that asserts <code class="computeroutput"><span class="identifier">inc</span></code> precondition. 146 </li> 147<li class="listitem"> 148 Then, execute <code class="computeroutput"><span class="identifier">inc</span></code> body 149 (i.e., all the code that follows the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="special">...</span></code> declaration). 150 </li> 151<li class="listitem"> 152 Last, execute the functor passed to <code class="computeroutput"><span class="special">.</span><span class="identifier">postcondition</span><span class="special">(...)</span></code> 153 that asserts <code class="computeroutput"><span class="identifier">inc</span></code> postcondition 154 (unless <code class="computeroutput"><span class="identifier">inc</span></code> body threw 155 an exception). 156 </li> 157</ul></div> 158<p> 159 For example, if there is a bug in the code calling <code class="computeroutput"><span class="identifier">inc</span></code> 160 so that the function is called with <code class="computeroutput"><span class="identifier">x</span></code> 161 equal to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span></code> then the program will terminate with an error 162 message similar to the following (and it will be evident that the bug is in 163 the calling code): 164 </p> 165<pre class="programlisting">precondition assertion "x < std::numeric_limits<int>::max()" failed: file "introduction.cpp", line 17 166</pre> 167<p> 168 Instead, if there is a bug in the implementation of <code class="computeroutput"><span class="identifier">inc</span></code> 169 so that <code class="computeroutput"><span class="identifier">x</span></code> is not incremented 170 by <code class="computeroutput"><span class="number">1</span></code> after the execution of the 171 function body then the program will terminate with an error message similar 172 to the following (and it will be evident that the bug is in <code class="computeroutput"><span class="identifier">inc</span></code> 173 body): <a href="#ftn.boost_contract.introduction.f0" class="footnote" name="boost_contract.introduction.f0"><sup class="footnote">[2]</sup></a> 174 </p> 175<pre class="programlisting">postcondition assertion "x == *old_x + 1" failed: file "introduction.cpp", line 20 176</pre> 177<p> 178 By default, when an assertion fails this library prints an error message such 179 the ones above to the standard error <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span></code> and 180 terminates the program calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span></code> 181 (this behaviour can be customized to take any user-specified action including 182 throwing exceptions, see <a class="link" href="boost_contract/advanced.html#boost_contract.advanced.throw_on_failures__and__noexcept__" title="Throw on Failures (and noexcept)">Throw 183 on Failures</a>). Note that the error messages printed by this library contain 184 all the information necessary to easily and uniquely identify the point in 185 the code at which contract assertions fail. <a href="#ftn.boost_contract.introduction.f1" class="footnote" name="boost_contract.introduction.f1"><sup class="footnote">[3]</sup></a> 186 </p> 187<div class="note"><table border="0" summary="Note"> 188<tr> 189<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../doc/src/images/note.png"></td> 190<th align="left">Note</th> 191</tr> 192<tr><td align="left" valign="top"><p> 193 C++11 lambda functions are necessary to use this library without manually 194 writing a significant amount of boiler-plate code to program functors that 195 assert the contracts (see <a class="link" href="boost_contract/extras.html#boost_contract.extras.no_lambda_functions__no_c__11_" title="No Lambda Functions (No C++11)">No 196 Lambda Functions</a>). That said, this library implementation does not 197 use C++11 features and should work on most modern C++ compilers (see <a class="link" href="boost_contract/getting_started.html" title="Getting Started">Getting Started</a>). 198 </p></td></tr> 199</table></div> 200<p> 201 In addition to contracts for non-member functions as shown the in the example 202 above, this library allows to program contracts for constructors, destructors, 203 and member functions. These can check class invariants and can also <span class="emphasis"><em>subcontract</em></span> 204 inheriting and extending contracts from base classes (see <a href="../../example/features/introduction_public.cpp" target="_top"><code class="literal">introduction_public.cpp</code></a> 205 and <a class="link" href="boost_contract/tutorial.html#boost_contract.tutorial.public_function_overrides__subcontracting_" title="Public Function Overrides (Subcontracting)">Public 206 Function Overrides</a>): <a href="#ftn.boost_contract.introduction.f2" class="footnote" name="boost_contract.introduction.f2"><sup class="footnote">[4]</sup></a> 207 </p> 208<p> 209</p> 210<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 211<span class="keyword">class</span> <span class="identifier">vector</span> 212 <span class="preprocessor">#define</span> <span class="identifier">BASES</span> <span class="keyword">public</span> <span class="identifier">pushable</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> 213 <span class="special">:</span> <span class="identifier">BASES</span> 214<span class="special">{</span> 215<span class="keyword">public</span><span class="special">:</span> 216 <span class="keyword">typedef</span> <span class="identifier">BOOST_CONTRACT_BASE_TYPES</span><span class="special">(</span><span class="identifier">BASES</span><span class="special">)</span> <span class="identifier">base_types</span><span class="special">;</span> <span class="comment">// For subcontracting.</span> 217 <span class="preprocessor">#undef</span> <span class="identifier">BASES</span> 218 219 <span class="keyword">void</span> <span class="identifier">invariant</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="comment">// Checked in AND with base class invariants.</span> 220 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><=</span> <span class="identifier">capacity</span><span class="special">());</span> 221 <span class="special">}</span> 222 223 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">push_back</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">,</span> 224 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">virtual_</span><span class="special">*</span> <span class="identifier">v</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="comment">/* override */</span> <span class="special">{</span> <span class="comment">// For virtuals.</span> 225 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">old_ptr</span><span class="special"><</span><span class="keyword">unsigned</span><span class="special">></span> <span class="identifier">old_size</span> <span class="special">=</span> 226 <span class="identifier">BOOST_CONTRACT_OLDOF</span><span class="special">(</span><span class="identifier">v</span><span class="special">,</span> <span class="identifier">size</span><span class="special">());</span> <span class="comment">// Old values for virtuals.</span> 227 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">check</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">contract</span><span class="special">::</span><span class="identifier">public_function</span><span class="special"><</span> <span class="comment">// For overrides.</span> 228 <span class="identifier">override_push_back</span><span class="special">>(</span><span class="identifier">v</span><span class="special">,</span> <span class="special">&</span><span class="identifier">vector</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">,</span> <span class="keyword">this</span><span class="special">,</span> <span class="identifier">value</span><span class="special">)</span> 229 <span class="special">.</span><span class="identifier">precondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Checked in OR with base preconditions.</span> 230 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special"><</span> <span class="identifier">max_size</span><span class="special">());</span> 231 <span class="special">})</span> 232 <span class="special">.</span><span class="identifier">postcondition</span><span class="special">([&]</span> <span class="special">{</span> <span class="comment">// Checked in AND with base postconditions.</span> 233 <span class="identifier">BOOST_CONTRACT_ASSERT</span><span class="special">(</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="special">*</span><span class="identifier">old_size</span> <span class="special">+</span> <span class="number">1</span><span class="special">);</span> 234 <span class="special">})</span> 235 <span class="special">;</span> 236 237 <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</span> 238 <span class="special">}</span> 239 <span class="identifier">BOOST_CONTRACT_OVERRIDE</span><span class="special">(</span><span class="identifier">push_back</span><span class="special">)</span> <span class="comment">// Define `override_push_back` above.</span> 240 241 <span class="comment">// Could program contracts for those as well.</span> 242 <span class="keyword">unsigned</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">}</span> 243 <span class="keyword">unsigned</span> <span class="identifier">max_size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">max_size</span><span class="special">();</span> <span class="special">}</span> 244 <span class="keyword">unsigned</span> <span class="identifier">capacity</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">vect_</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">();</span> <span class="special">}</span> 245 246<span class="keyword">private</span><span class="special">:</span> 247 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">vect_</span><span class="special">;</span> 248<span class="special">};</span> 249</pre> 250<p> 251 </p> 252<h4> 253<a name="boost_contract.introduction.h0"></a> 254 <span class="phrase"><a name="boost_contract.introduction.language_support"></a></span><a class="link" href="index.html#boost_contract.introduction.language_support">Language 255 Support</a> 256 </h4> 257<p> 258 The authors of this library advocate for contracts to be added to the core 259 language. Adding contract programming to the C++ standard has a number of advantages 260 over any library implementation (shorter and more concise syntax to program 261 contracts, specify contracts in declarations instead of definitions, enforce 262 contract constant-correctness, expected faster compile- and run-time, vendors 263 could develop static analysis tools to recognize and check contracts statically 264 when possible, compiler optimizations could be improved based on contract conditions, 265 etc.). 266 </p> 267<p> 268 The <a class="link" href="boost_contract/bibliography.html#P0380_anchor">[P0380]</a> proposal supports basic contract 269 programming, it was accepted and it will be included in C++20. This is undoubtedly 270 a step in the right direction, but unfortunately <a class="link" href="boost_contract/bibliography.html#P0380_anchor">[P0380]</a> 271 only supports pre- and postconditions while missing important features such 272 as class invariants and old values in postconditions, not to mention the lack 273 of more advanced features like subcontracting (more complete proposals like 274 <a class="link" href="boost_contract/bibliography.html#N1962_anchor">[N1962]</a> were rejected by the C++ standard 275 committee). All contracting programming features are instead supported by this 276 library (see <a class="link" href="boost_contract/contract_programming_overview.html#boost_contract.contract_programming_overview.feature_summary" title="Feature Summary">Feature 277 Summary</a> for a detailed comparison between the features supported by 278 this library and the ones listed in different contract programming proposals, 279 see <a class="link" href="boost_contract/bibliography.html" title="Bibliography">Bibliography</a> for a list 280 of references considered during the design and implementation of this library, 281 including the vast majority of contract programming proposals submitted to 282 the C++ standard committee). 283 </p> 284</div> 285<div class="footnotes"> 286<br><hr style="width:100; text-align:left;margin-left: 0"> 287<div id="ftn.boost_contract.f0" class="footnote"><p><a href="#boost_contract.f0" class="para"><sup class="para">[1] </sup></a> 288 Design by Contract (DbC) is a registered trademark of the Eiffel Software company 289 and it was first introduced by the Eiffel programming language (see <a class="link" href="boost_contract/bibliography.html#Meyer97_anchor">[Meyer97]</a>). 290 </p></div> 291<div id="ftn.boost_contract.introduction.f0" class="footnote"><p><a href="#boost_contract.introduction.f0" class="para"><sup class="para">[2] </sup></a> 292 In this example the function body is composed of a single trivial instruction 293 <code class="computeroutput"><span class="special">++</span><span class="identifier">x</span></code> 294 so it easy to check by visual inspection that it does not contain any bug 295 and it will always increment <code class="computeroutput"><span class="identifier">x</span></code> 296 by <code class="computeroutput"><span class="number">1</span></code> thus the function postcondition 297 will never fail. In real production code, function bodies are rarely this 298 simple and can hide bugs which make checking postconditions useful. 299 </p></div> 300<div id="ftn.boost_contract.introduction.f1" class="footnote"><p><a href="#boost_contract.introduction.f1" class="para"><sup class="para">[3] </sup></a> 301 <span class="bold"><strong>Rationale:</strong></span> The assertion failure message 302 printed by this library follows a format similar to the message printed by 303 Clang when the C-style <code class="computeroutput"><span class="identifier">assert</span></code> 304 macro fails. 305 </p></div> 306<div id="ftn.boost_contract.introduction.f2" class="footnote"><p><a href="#boost_contract.introduction.f2" class="para"><sup class="para">[4] </sup></a> 307 The <code class="computeroutput"><span class="identifier">pushable</span></code> base class is 308 used in this example just to show subcontracting, it is somewhat arbitrary 309 and it will likely not appear in real production code. 310 </p></div> 311</div> 312</div> 313<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 314<td align="left"><p><small>Last revised: August 11, 2020 at 15:01:27 GMT</small></p></td> 315<td align="right"><div class="copyright-footer"></div></td> 316</tr></table> 317<hr> 318<div class="spirit-nav"><a accesskey="n" href="boost_contract/full_table_of_contents.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div> 319</body> 320</html> 321