2.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Using safe_range and safe_literal</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="../eliminate_runtime_penalty.html" title="Eliminating Runtime Penalty">
  9. <link rel="prev" href="../eliminate_runtime_penalty.html" title="Eliminating Runtime Penalty">
  10. <link rel="next" href="1.html" title="Using Automatic Type Promotion">
  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="../eliminate_runtime_penalty.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../eliminate_runtime_penalty.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="1.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.eliminate_runtime_penalty.2"></a>Using <a class="link" href="safe_range.html" title="safe_signed_range&lt;MIN, MAX, PP, EP&gt; and safe_unsigned_range&lt;MIN, MAX, PP, EP&gt;">safe_range</a>
  23. and <a class="link" href="safe_literal.html" title="safe_signed_literal&lt;Value, PP , EP&gt; and safe_unsigned_literal&lt;Value, PP, EP&gt;">safe_literal</a>
  24. </h3></div></div></div>
  25. <p>When trying to avoid arithmetic errors of the above type,
  26. programmers will select data types which are wide enough to hold values
  27. large enough to be certain that results won't overflow, but are not so
  28. large as to make the program needlessly inefficient. In the example below,
  29. we presume we know that the values we want to work with fall in the range
  30. [-24,82]. So we "know" the program will always result in a correct result.
  31. But since we trust no one, and since the program could change and the
  32. expressions be replaced with other ones, we'll still use the <a class="link" href="exception_policies.html#safe_numerics.exception_policies.loose_trap_policy"><code class="computeroutput">loose_trap_policy</code></a>
  33. exception policy to verify at compile time that what we "know" to be true
  34. is in fact true.</p>
  35. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
  36. <span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
  37. <span class="preprocessor">#include</span> <span class="special">&lt;</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_literal</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  38. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">safe_numerics</span><span class="special">/</span><span class="identifier">exception</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  39. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">safe_numerics</span><span class="special">/</span><span class="identifier">native</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  40. <span class="preprocessor">#include</span> <span class="string">"safe_format.hpp"</span> <span class="comment">// prints out range and value of any type</span>
  41. <span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">safe_numerics</span><span class="special">;</span>
  42. <span class="comment">// create a type for holding small integers in a specific range</span>
  43. <span class="keyword">using</span> <span class="identifier">safe_t</span> <span class="special">=</span> <span class="identifier">safe_signed_range</span><span class="special">&lt;</span>
  44. <span class="special">-</span><span class="number">24</span><span class="special">,</span>
  45. <span class="number">82</span><span class="special">,</span>
  46. <span class="identifier">native</span><span class="special">,</span> <span class="comment">// C++ type promotion rules work OK for this example</span>
  47. <span class="identifier">loose_trap_policy</span> <span class="comment">// catch problems at compile time</span>
  48. <span class="special">&gt;</span><span class="special">;</span>
  49. <span class="comment">// create a type to hold one specific value</span>
  50. <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="identifier">I</span><span class="special">&gt;</span>
  51. <span class="keyword">using</span> <span class="identifier">const_safe_t</span> <span class="special">=</span> <span class="identifier">safe_signed_literal</span><span class="special">&lt;</span><span class="identifier">I</span><span class="special">,</span> <span class="identifier">native</span><span class="special">,</span> <span class="identifier">loose_trap_policy</span><span class="special">&gt;</span><span class="special">;</span>
  52. <span class="comment">// We "know" that C++ type promotion rules will work such that</span>
  53. <span class="comment">// addition will never overflow. If we change the program to break this,</span>
  54. <span class="comment">// the usage of the loose_trap_policy promotion policy will prevent compilation.</span>
  55. <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>
  56. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"example 83:\n"</span><span class="special">;</span>
  57. <span class="keyword">constexpr</span> <span class="keyword">const</span> <span class="identifier">const_safe_t</span><span class="special">&lt;</span><span class="number">10</span><span class="special">&gt;</span> <span class="identifier">x</span><span class="special">;</span>
  58. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">safe_format</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  59. <span class="keyword">constexpr</span> <span class="keyword">const</span> <span class="identifier">const_safe_t</span><span class="special">&lt;</span><span class="number">67</span><span class="special">&gt;</span> <span class="identifier">y</span><span class="special">;</span>
  60. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"y = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">safe_format</span><span class="special">(</span><span class="identifier">y</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  61. <span class="keyword">const</span> <span class="identifier">safe_t</span> <span class="identifier">z</span> <span class="special">=</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span>
  62. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"x + y = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">safe_format</span><span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  63. <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"z = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">safe_format</span><span class="special">(</span><span class="identifier">z</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  64. <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
  65. <span class="special">}</span>
  66. </pre>
  67. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  68. <li class="listitem"><p><code class="computeroutput"><code class="computeroutput">safe_signed_range</code></code> defines a type
  69. which is limited to the indicated range. Out of range assignments
  70. will be detected at compile time if possible (as in this case) or at
  71. run time if necessary.</p></li>
  72. <li class="listitem"><p>A safe range could be defined with the same minimum and
  73. maximum value effectively restricting the type to holding one
  74. specific value. This is what <code class="computeroutput">safe_signed_literal</code>
  75. does.</p></li>
  76. <li class="listitem"><p>Defining constants with <code class="computeroutput">safe_signed_literal</code>
  77. enables the library to correctly anticipate the correct range of the
  78. results of arithmetic expressions at compile time.</p></li>
  79. <li class="listitem"><p>The usage of <code class="computeroutput"><a class="link" href="exception_policies.html#safe_numerics.exception_policies.loose_trap_policy"><code class="computeroutput">loose_trap_policy</code></a></code>
  80. will mean that any assignment to z which could be outside its legal
  81. range will result in a compile time error.</p></li>
  82. <li class="listitem"><p>All safe integer operations are implemented as constant
  83. expressions. The usage of <code class="computeroutput">constexpr</code> will guarantee that
  84. <code class="computeroutput">z</code> will be available at compile time for any subsequent
  85. use.</p></li>
  86. <li class="listitem"><p>So if this program compiles, it's guaranteed to return a valid
  87. result.</p></li>
  88. </ul></div>
  89. <p>The output uses a custom output manipulator,
  90. <code class="computeroutput">safe_format</code>, for safe types to display the underlying type
  91. and its range as well as current value. This program produces the
  92. following run time output.</p>
  93. <pre class="screen">example 83:
  94. x = &lt;signed char&gt;[10,10] = 10
  95. y = &lt;signed char&gt;[67,67] = 67
  96. x + y = &lt;int&gt;[77,77] = 77
  97. z = &lt;signed char&gt;[-24,82] = 77</pre>
  98. <p>Take note of the various variable types:</p>
  99. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  100. <li class="listitem"><p><code class="computeroutput">x</code> and <code class="computeroutput">y</code> are safe types with fixed
  101. ranges which encompass one single value. They can hold only that
  102. value which they have been assigned at compile time.</p></li>
  103. <li class="listitem"><p><code class="computeroutput">The sum x + y can also be determined at compile
  104. time.</code></p></li>
  105. <li class="listitem"><p>The type of z is defined so that It can hold only values in
  106. the closed range -24,82. We can assign the sum of x + y because it
  107. is in the range that <code class="computeroutput">z</code> is guaranteed to hold. If the
  108. sum could not be be guaranteed to fall in the range of
  109. <code class="computeroutput">z</code>, we would get a compile time error due to the fact we
  110. are using the <code class="computeroutput">loose_trap_policy</code> exception
  111. policy.</p></li>
  112. </ul></div>
  113. <p>All this information regarding the range and values of
  114. variables has been determined at compile time. There is no runtime
  115. overhead. The usage of safe types does not alter the calculations or
  116. results in anyway. So <code class="computeroutput">safe_t</code> and <code class="computeroutput">const_safe_t</code>
  117. could be redefined to <code class="computeroutput">int</code> and <code class="computeroutput">const int</code>
  118. respectively and the program would operate identically - although it might
  119. We could compile the program for another machine - as is common when
  120. building embedded systems and know (assuming the target machine
  121. architecture was the same as our native one) that no erroneous results
  122. would ever be produced.</p>
  123. </div>
  124. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  125. <td align="left"></td>
  126. <td align="right"><div class="copyright-footer">Copyright &#169; 2012-2018 Robert Ramey<p><a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">Subject to Boost
  127. Software License</a></p>
  128. </div></td>
  129. </tr></table>
  130. <hr>
  131. <div class="spirit-nav">
  132. <a accesskey="p" href="../eliminate_runtime_penalty.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../eliminate_runtime_penalty.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="1.html"><img src="../images/next.png" alt="Next"></a>
  133. </div>
  134. </body>
  135. </html>