1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN"> 2 3<html> 4<head> 5<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 6<title>Boost.MultiIndex Documentation - Tutorial -Debugging support</title> 7<link rel="stylesheet" href="../style.css" type="text/css"> 8<link rel="start" href="../index.html"> 9<link rel="prev" href="creation.html"> 10<link rel="up" href="index.html"> 11<link rel="next" href="techniques.html"> 12</head> 13 14<body> 15<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align= 16"middle" width="277" height="86">Boost.MultiIndex Tutorial: Debugging support</h1> 17 18<div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br> 19Container creation 20</a></div> 21<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br> 22Boost.MultiIndex tutorial 23</a></div> 24<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br> 25Techniques 26</a></div><br clear="all" style="clear: all;"> 27 28<hr> 29 30<h2>Contents</h2> 31 32<ul> 33 <li><a href="#debugging_support">Debugging support</a></li> 34 <li><a href="#safe_mode">Safe mode</a> 35 <ul> 36 <li><a href="#serialization_and_safe_mode">Serialization and safe mode</a></li> 37 </ul> 38 </li> 39 <li><a href="#invariant_check">Invariant-checking mode</a></li> 40</ul> 41 42<h2><a name="debugging_support">Debugging support</a></h2> 43 44<p> 45The concept of <i>Design by Contract</i>, originally developed as part 46of Bertrand Meyer's <a href="http://www.eiffel.com">Eiffel</a> language, 47revolves around the formulation of a <i>contract</i> between the user 48of a library and the implementor, by which the first is required to 49respect some <i>preconditions</i> on the values passed when invoking 50methods of the library, and the implementor guarantees in return 51that certain constraints on the results are met (<i>postconditions</i>), 52as well as the honoring of specified internal consistency rules, called 53<i>invariants</i>. Eiffel natively supports the three parts of the 54contract just described by means of constructs <code>require</code>, 55<code>ensure</code> and <code>invariant</code>, respectively. 56</p> 57 58<p> 59C++ does not enjoy direct support for Design by Contract techniques: these 60are customarily implemented as assertion code, often turned off in 61release mode for performance reasons. Following this approach, 62Boost.MultiIndex provides two distinct debugging modes: 63<ul> 64 <li><i>Safe mode</i> checks preconditions on the invocations to the 65 facilities of the library,</li> 66 <li><i>invariant-checking mode</i> performs post-execution checks aimed 67 at ensuring that the internal consistency of the library is preserved.</li> 68</ul> 69These two modes are independent of each other and can be set on or off 70individually. It is important to note that errors detected by safe mode are 71due in principle to faulty code in the user's program, while 72invariant-checking mode detects potential <i>internal</i> bugs in the 73implementation of Boost.MultiIndex. 74</p> 75 76<h2><a name="safe_mode">Safe mode</a></h2> 77 78<p> 79The idea of adding precondition checking facilities to STL as a debugging aid 80was first introduced by Cay S. Horstmann in his 81<a href="http://www.horstmann.com/safestl.html">Safe STL</a> library and later 82adopted by <a href="http://www.stlport.com/doc/debug_mode.html">STLport Debug 83Mode</a>. Similarly, Boost.MultiIndex features the so-called <i>safe mode</i> 84in which all sorts of preconditions are checked when dealing with iterators 85and functions of the library. 86</p> 87 88<p> 89Boost.MultiIndex safe mode is set by globally defining the macro 90<code>BOOST_MULTI_INDEX_ENABLE_SAFE_MODE</code>. Error conditions 91are checked via the macro <code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, which 92by default resolves to a call to <a href="../../../../libs/assert"> 93<code>BOOST_ASSERT</code></a>. 94</p> 95 96<p> 97If the user decides to define her own version of 98<code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code>, it has to take the form 99</p> 100 101<blockquote><pre> 102<span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span> 103</pre></blockquote> 104 105<p> 106where <code>expr</code> is the condition checked and <code>error_code</code> 107is one value of the <code>safe_mode::error_code</code> enumeration: 108</p> 109 110<blockquote><pre> 111<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span> 112 113<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span> 114 115<span class=keyword>namespace</span> <span class=identifier>safe_mode</span><span class=special>{</span> 116 117<span class=keyword>enum</span> <span class=identifier>error_code</span> 118<span class=special>{</span> 119 <span class=identifier>invalid_iterator</span><span class=special>,</span> <span class=comment>// vg. default cted or pointing to erased element</span> 120 <span class=identifier>not_dereferenceable_iterator</span><span class=special>,</span> <span class=comment>// iterator is not dereferenceable</span> 121 <span class=identifier>not_incrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to end of sequence</span> 122 <span class=identifier>not_decrementable_iterator</span><span class=special>,</span> <span class=comment>// iterator points to beginning of sequence</span> 123 <span class=identifier>not_owner</span><span class=special>,</span> <span class=comment>// iterator does not belong to the container</span> 124 <span class=identifier>not_same_owner</span><span class=special>,</span> <span class=comment>// iterators belong to different containers</span> 125 <span class=identifier>invalid_range</span><span class=special>,</span> <span class=comment>// last not reachable from first</span> 126 <span class=identifier>inside_range</span><span class=special>,</span> <span class=comment>// iterator lies within a range (and it mustn't)</span> 127 <span class=identifier>out_of_bounds</span><span class=special>,</span> <span class=comment>// move attempted beyond container limits</span> 128 <span class=identifier>same_container</span><span class=special>,</span> <span class=comment>// containers ought to be different</span> 129 <span class=identifier>unequal_allocators</span> <span class=comment>// allocators ought to be equal</span> 130<span class=special>};</span> 131 132<span class=special>}</span> <span class=comment>// namespace multi_index::safe_mode</span> 133 134<span class=special>}</span> <span class=comment>// namespace multi_index</span> 135 136<span class=special>}</span> <span class=comment>// namespace boost</span> 137</pre></blockquote> 138 139<p> 140For instance, the following replacement of 141<code>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</code> throws an exception instead of 142asserting: 143</p> 144 145<blockquote><pre> 146<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>multi_index_container</span><span class=special>/</span><span class=identifier>safe_mode_errors</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>></span> 147 148<span class=keyword>struct</span> <span class=identifier>safe_mode_exception</span> 149<span class=special>{</span> 150 <span class=identifier>safe_mode_exception</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>):</span> 151 <span class=identifier>error_code</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>)</span> 152 <span class=special>{}</span> 153 154 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>safe_mode</span><span class=special>::</span><span class=identifier>error_code</span> <span class=identifier>error_code</span><span class=special>;</span> 155<span class=special>};</span> 156 157<span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_SAFE_MODE_ASSERT</span><span class=special>(</span><span class=identifier>expr</span><span class=special>,</span><span class=identifier>error_code</span><span class=special>)</span> <span class=special>\</span> 158<span class=keyword>if</span><span class=special>(!(</span><span class=identifier>expr</span><span class=special>)){</span><span class=keyword>throw</span> <span class=identifier>safe_mode_exception</span><span class=special>(</span><span class=identifier>error_code</span><span class=special>);}</span> 159 160<span class=comment>// This has to go before the inclusion of any header from Boost.MultiIndex, 161// except possibly safe_error_codes.hpp.</span> 162</pre></blockquote> 163 164<p> 165Other possibilites, like outputting to a log or firing some kind of alert, are 166also implementable. 167</p> 168 169<p> 170<b>Warning:</b> Safe mode adds a very important overhead to the program 171both in terms of space and time used, so in general it should not be set for 172<code>NDEBUG</code> builds. Also, this mode is intended solely as a debugging aid, 173and programs must not rely on it as part of their normal execution flow: in 174particular, no guarantee is made that all possible precondition errors are diagnosed, 175or that the checks remain stable across different versions of the library. 176</p> 177 178<h3><a name="serialization_and_safe_mode">Serialization and safe mode</a></h3> 179 180<p> 181Iterators restored from an archive are not subject to safe mode checks. This is 182so because it is not possible to automatically know the associated 183<code>multi_index_container</code> of an iterator from the serialization 184information alone. However, if desired, a restored iterator can be converted to a 185checked value by using the following workaround: 186</p> 187 188<blockquote><pre> 189<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span> 190<span class=identifier>employee_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>;</span> 191 192<span class=comment>// restore es and it from an archive ar</span> 193<span class=identifier>ar</span><span class=special>>></span><span class=identifier>es</span><span class=special>;</span> 194<span class=identifier>ar</span><span class=special>>></span><span class=identifier>it</span><span class=special>;</span> <span class=comment>// it won't benefit from safe mode checks 195 196// Turn it into a checked value by providing Boost.MultiIndex 197// with info about the associated container. 198// This statement has virtually zero cost if safe mode is turned off.</span> 199<span class=identifier>it</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>project</span><span class=special><</span><span class=number>1</span><span class=special>>(</span><span class=identifier>it</span><span class=special>);</span> 200</pre></blockquote> 201 202<h2><a name="invariant_check">Invariant-checking mode</a></h2> 203 204<p> 205The so called <i>invariant-checking mode</i> of Boost.MultiIndex can be 206set by globally defining the macro 207<code>BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING</code>. 208When this mode is in effect, all public functions of Boost.MultiIndex 209will perform post-execution tests aimed at ensuring that the basic 210internal invariants of the data structures managed are preserved. 211</p> 212 213<p> 214If an invariant test fails, Boost.MultiIndex will indicate the failure 215by means of the unary macro <code>BOOST_MULTI_INDEX_INVARIANT_ASSERT</code>. 216Unless the user provides a definition for this macro, it defaults to 217<a href="../../../../libs/assert"> 218<code>BOOST_ASSERT</code></a>. Any assertion of this kind should 219be regarded in principle as a bug in the library. Please report such 220problems, along with as much contextual information as possible, to the 221maintainer of the library. 222</p> 223 224<p> 225It is recommended that users of Boost.MultiIndex always set the 226invariant-checking mode in debug builds. 227</p> 228 229<hr> 230 231<div class="prev_link"><a href="creation.html"><img src="../prev.gif" alt="container creation" border="0"><br> 232Container creation 233</a></div> 234<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br> 235Boost.MultiIndex tutorial 236</a></div> 237<div class="next_link"><a href="techniques.html"><img src="../next.gif" alt="techniques" border="0"><br> 238Techniques 239</a></div><br clear="all" style="clear: all;"> 240 241<br> 242 243<p>Revised May 9th 2020</p> 244 245<p>© Copyright 2003-2020 Joaquín M López Muñoz. 246Distributed under the Boost Software 247License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 248LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> 249http://www.boost.org/LICENSE_1_0.txt</a>) 250</p> 251 252</body> 253</html> 254