1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> 4<title>Programming by Contract is Too Slow</title> 5<link rel="stylesheet" href="../boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../index.html" title="Safe Numerics"> 8<link rel="up" href="../tutorial.html" title="Tutorial and Motivating Examples"> 9<link rel="prev" href="9.html" title="Compile Time Arithmetic is Not Always Correct"> 10<link rel="next" href="../eliminate_runtime_penalty.html" title="Eliminating Runtime Penalty"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img href="index.html" height="164px" src="pre-boost.jpg" alt="Library Documentation Index"></td> 15<td><h2>Safe Numerics</h2></td> 16</tr></table> 17<div class="spirit-nav"> 18<a accesskey="p" href="9.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="../eliminate_runtime_penalty.html"><img src="../images/next.png" alt="Next"></a> 19</div> 20<div class="section"> 21<div class="titlepage"><div><div><h3 class="title"> 22<a name="safe_numerics.tutorial.10"></a>Programming by Contract is Too Slow</h3></div></div></div> 23<p>Programming by Contract is a highly regarded technique. There has 24 been much written about it and it has been proposed as an addition to the 25 C++ language [<span class="citation"><a class="xref" href="bibliography.html#garcia" title="C++ language support for contract programming"><abbr class="abbrev">Garcia</abbr></a></span>][<span class="citation"><a class="xref" href="bibliography.html#crowl2" title="Proposal to add Contract Programming to C++"><abbr class="abbrev">Crowl & Ottosen</abbr></a></span>] It (mostly) depends upon runtime checking of 26 parameter and object values upon entry to and exit from every function. 27 This can slow the program down considerably which in turn undermines the 28 main motivation for using C++ in the first place! One popular scheme for 29 addressing this issue is to enable parameter checking only during 30 debugging and testing which defeats the guarantee of correctness which we 31 are seeking here! Programming by Contract will never be accepted by 32 programmers as long as it is associated with significant additional 33 runtime cost.</p> 34<p>The Safe Numerics Library has facilities which, in many cases, can 35 check guaranteed parameter requirements with little or no runtime 36 overhead. Consider the following example:</p> 37<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span> 38<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">stdexcept</span><span class="special">></span> 39<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span> 40<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 41 42<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">safe_numerics</span><span class="special">/</span><span class="identifier">safe_integer_range</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 43 44<span class="comment">// NOT using safe numerics - enforce program contract explicitly</span> 45<span class="comment">// return total number of minutes</span> 46<span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">contract_convert</span><span class="special">(</span> 47 <span class="keyword">const</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&</span> <span class="identifier">hours</span><span class="special">,</span> 48 <span class="keyword">const</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&</span> <span class="identifier">minutes</span> 49<span class="special">)</span> <span class="special">{</span> 50 <span class="comment">// check that parameters are within required limits</span> 51 <span class="comment">// invokes a runtime cost EVERYTIME the function is called</span> 52 <span class="comment">// and the overhead of supporting an interrupt.</span> 53 <span class="comment">// note high runtime cost!</span> 54 <span class="keyword">if</span><span class="special">(</span><span class="identifier">minutes</span> <span class="special">></span> <span class="number">59</span><span class="special">)</span> 55 <span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span><span class="special">(</span><span class="string">"minutes exceeded 59"</span><span class="special">)</span><span class="special">;</span> 56 <span class="keyword">if</span><span class="special">(</span><span class="identifier">hours</span> <span class="special">></span> <span class="number">23</span><span class="special">)</span> 57 <span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">domain_error</span><span class="special">(</span><span class="string">"hours exceeded 23"</span><span class="special">)</span><span class="special">;</span> 58 <span class="keyword">return</span> <span class="identifier">hours</span> <span class="special">*</span> <span class="number">60</span> <span class="special">+</span> <span class="identifier">minutes</span><span class="special">;</span> 59<span class="special">}</span> 60 61<span class="comment">// Use safe numerics to enforce program contract automatically</span> 62<span class="comment">// define convenient typenames for hours and minutes hh:mm</span> 63<span class="keyword">using</span> <span class="identifier">hours_t</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">safe_numerics</span><span class="special">::</span><span class="identifier">safe_unsigned_range</span><span class="special"><</span><span class="number">0</span><span class="special">,</span> <span class="number">23</span><span class="special">></span><span class="special">;</span> 64<span class="keyword">using</span> <span class="identifier">minutes_t</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">safe_numerics</span><span class="special">::</span><span class="identifier">safe_unsigned_range</span><span class="special"><</span><span class="number">0</span><span class="special">,</span> <span class="number">59</span><span class="special">></span><span class="special">;</span> 65<span class="keyword">using</span> <span class="identifier">minutes_total_t</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">safe_numerics</span><span class="special">::</span><span class="identifier">safe_unsigned_range</span><span class="special"><</span><span class="number">0</span><span class="special">,</span> <span class="number">59</span><span class="special">></span><span class="special">;</span> 66 67<span class="comment">// return total number of minutes</span> 68<span class="comment">// type returned is safe_unsigned_range<0, 24*60 - 1></span> 69<span class="keyword">auto</span> <span class="identifier">convert</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">hours_t</span> <span class="special">&</span> <span class="identifier">hours</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">minutes_t</span> <span class="special">&</span> <span class="identifier">minutes</span><span class="special">)</span> <span class="special">{</span> 70 <span class="comment">// no need to test pre-conditions</span> 71 <span class="comment">// input parameters are guaranteed to hold legitimate values</span> 72 <span class="comment">// no need to test post-conditions</span> 73 <span class="comment">// return value guaranteed to hold result</span> 74 <span class="keyword">return</span> <span class="identifier">hours</span> <span class="special">*</span> <span class="number">60</span> <span class="special">+</span> <span class="identifier">minutes</span><span class="special">;</span> 75<span class="special">}</span> 76 77<span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">test1</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">hours</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">minutes</span><span class="special">)</span><span class="special">{</span> 78 <span class="comment">// problem: checking of externally produced value can be expensive</span> 79 <span class="comment">// invalid parameters - detected - but at a heavy cost</span> 80 <span class="keyword">return</span> <span class="identifier">contract_convert</span><span class="special">(</span><span class="identifier">hours</span><span class="special">,</span> <span class="identifier">minutes</span><span class="special">)</span><span class="special">;</span> 81<span class="special">}</span> 82 83<span class="keyword">auto</span> <span class="identifier">test2</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">hours</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">minutes</span><span class="special">)</span><span class="special">{</span> 84 <span class="comment">// solution: use safe numerics</span> 85 <span class="comment">// safe types can be implicitly constructed base types</span> 86 <span class="comment">// construction guarentees corectness</span> 87 <span class="comment">// return value is known to fit in unsigned int</span> 88 <span class="keyword">return</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">hours</span><span class="special">,</span> <span class="identifier">minutes</span><span class="special">)</span><span class="special">;</span> 89<span class="special">}</span> 90 91<span class="keyword">auto</span> <span class="identifier">test3</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">hours</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">minutes</span><span class="special">)</span><span class="special">{</span> 92 <span class="comment">// actually we don't even need the convert function any more</span> 93 <span class="keyword">return</span> <span class="identifier">hours_t</span><span class="special">(</span><span class="identifier">hours</span><span class="special">)</span> <span class="special">*</span> <span class="number">60</span> <span class="special">+</span> <span class="identifier">minutes_t</span><span class="special">(</span><span class="identifier">minutes</span><span class="special">)</span><span class="special">;</span> 94<span class="special">}</span> 95 96<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="special">[</span><span class="special">]</span><span class="special">)</span><span class="special">{</span> 97 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"example 7: "</span><span class="special">;</span> 98 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"enforce contracts with zero runtime cost"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 99 100 <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">total_minutes</span><span class="special">;</span> 101 102 <span class="keyword">try</span> <span class="special">{</span> 103 <span class="identifier">total_minutes</span> <span class="special">=</span> <span class="identifier">test3</span><span class="special">(</span><span class="number">17</span><span class="special">,</span> <span class="number">83</span><span class="special">)</span><span class="special">;</span> 104 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"total minutes = "</span> <span class="special"><<</span> <span class="identifier">total_minutes</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 105 <span class="special">}</span> 106 <span class="keyword">catch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span> <span class="special">&</span> <span class="identifier">e</span><span class="special">)</span><span class="special">{</span> 107 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"parameter error detected"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 108 <span class="special">}</span> 109 110 <span class="keyword">try</span> <span class="special">{</span> 111 <span class="identifier">total_minutes</span> <span class="special">=</span> <span class="identifier">test3</span><span class="special">(</span><span class="number">17</span><span class="special">,</span> <span class="number">10</span><span class="special">)</span><span class="special">;</span> 112 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"total minutes = "</span> <span class="special"><<</span> <span class="identifier">total_minutes</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 113 <span class="special">}</span> 114 <span class="keyword">catch</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span> <span class="special">&</span> <span class="identifier">e</span><span class="special">)</span><span class="special">{</span> 115 <span class="comment">// should never arrive here</span> 116 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"parameter error erroneously detected"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 117 <span class="keyword">return</span> <span class="number">1</span><span class="special">;</span> 118 <span class="special">}</span> 119 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 120<span class="special">}</span> 121</pre> 122<pre class="screen">example 8: 123enforce contracts with zero runtime cost 124parameter error detected</pre> 125<p>In the example above, the function <code class="computeroutput">convert</code> incurs 126 significant runtime cost every time the function is called. By using 127 "safe" types, this cost is moved to the moment when the parameters are 128 constructed. Depending on how the program is constructed, this may totally 129 eliminate extraneous computations for parameter requirement type checking. 130 In this scenario, there is no reason to suppress the checking for release 131 mode and our program can be guaranteed to be always arithmetically 132 correct.</p> 133</div> 134<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 135<td align="left"></td> 136<td align="right"><div class="copyright-footer">Copyright © 2012-2018 Robert Ramey<p><a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">Subject to Boost 137 Software License</a></p> 138</div></td> 139</tr></table> 140<hr> 141<div class="spirit-nav"> 142<a accesskey="p" href="9.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="../eliminate_runtime_penalty.html"><img src="../images/next.png" alt="Next"></a> 143</div> 144</body> 145</html> 146