safe_introduction.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE section PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
  3. "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
  4. <section id="safe_numerics.introduction">
  5. <title>Introduction</title>
  6. <?dbhtml stop-chunking?>
  7. <para>This library is intended as a drop-in replacement for all built-in
  8. integer types in any program which must:</para>
  9. <itemizedlist>
  10. <listitem>
  11. <para>be demonstrably and verifiably correct.</para>
  12. </listitem>
  13. <listitem>
  14. <para>detect every user error such as input, assignment, etc.</para>
  15. </listitem>
  16. <listitem>
  17. <para>be efficient as possible subject to the constraints above.</para>
  18. </listitem>
  19. </itemizedlist>
  20. <section id="safe_numerics.introduction.problem">
  21. <title>Problem</title>
  22. <para>Arithmetic operations in C/C++ are NOT guaranteed to yield a correct
  23. mathematical result. This feature is inherited from the early days of C.
  24. The behavior of <code>int</code>, <code>unsigned int</code> and others
  25. were designed to map closely to the underlying hardware. Computer hardware
  26. implements these types as a fixed number of bits. When the result of
  27. arithmetic operations exceeds this number of bits, the result will not be
  28. arithmetically correct. The following example illustrates just one example
  29. where this causes problems.</para>
  30. <programlisting>int f(int x, int y){
  31. // this returns an invalid result for some legal values of x and y !
  32. return x + y;
  33. }
  34. </programlisting>
  35. <para>It is incumbent upon the C/C++ programmer to guarantee that this
  36. behavior does not result in incorrect or unexpected operation of the
  37. program. There are no language facilities which implement such a
  38. guarantee. A programmer needs to examine each expression individually to
  39. know that his program will not return an invalid result. There are a
  40. number of ways to do this. In the above instance,
  41. <citation>INT32-C</citation> seems to recommend the following
  42. approach:</para>
  43. <programlisting>int f(int x, int y){
  44. if (((y &gt; 0) &amp;&amp; (x &gt; (INT_MAX - y)))
  45. || ((y &lt; 0) &amp;&amp; (x &lt; (INT_MIN - y)))) {
  46. /* Handle error */
  47. }
  48. return x + y;
  49. }
  50. </programlisting>
  51. <para>This will indeed trap the error. However, it would be tedious and
  52. laborious for a programmer to alter his code in this manner. Altering code
  53. in this way for all arithmetic operations would likely render the code
  54. unreadable and add another source of potential programming errors. This
  55. approach is clearly not functional when the expression is even a little
  56. more complex as is shown in the following example.</para>
  57. <programlisting>int f(int x, int y, int z){
  58. // this returns an invalid result for some legal values of x and y !
  59. return x + y * z;
  60. }
  61. </programlisting>
  62. <para>This example addresses only the problem of undefined/erroneous
  63. behavior related to overflow of the addition operation as applied to the
  64. type <code>int</code>. Similar problems occur with other built-in integer
  65. types such as <code>unsigned</code>, <code>long</code>, etc. And it also
  66. applies to other operations such as subtraction, multiplication etc. .
  67. C/C++ often automatically and silently converts some integer types to
  68. others in the course of implementing binary operations. Sometimes such
  69. conversions can silently change arithmetic values which inject errors. The
  70. C/C++ standards designate some behavior such as right shifting a negative
  71. number as "implementation defined behavior". These days machines usually
  72. do what the programmer expects - but such behavior is not guaranteed.
  73. Relying on such behavior will create a program which cannot be guaranteed
  74. to be portable. And then there is undefined behavior. In this case,
  75. compiler writer is under no obligation to do anything in particular.
  76. Sometimes this will unexpectedly break the program. At the very least, the
  77. program is rendered non-portable. Finally there is the case of behavior
  78. that is arithmetically wrong to begin with - for example divide by zero.
  79. Some runtime environments will just terminate the program, others may
  80. throw some sort of exception. In any case, the execution has failed in a
  81. manner from which there is no recovery.</para>
  82. <para>All of the above conditions are obstacles to creation of a program
  83. which will never fail. The Safe Numerics Library addresses all of these
  84. conditions, at least as far as integer operations are concerned.</para>
  85. <para>Since the problems and their solution are similar, we'll confine the
  86. current discussion to just the one example shown above.</para>
  87. </section>
  88. <section id="safe_numerics.introduction.solution">
  89. <title>Solution</title>
  90. <para>This library implements special versions of <code>int</code>,
  91. <code>unsigned</code>, etc. which behave exactly like the original ones
  92. <emphasis role="bold">except</emphasis> that the results of these
  93. operations are guaranteed to be either to be arithmetically correct or
  94. invoke an error. Using this library, the above example would be rendered
  95. as:</para>
  96. <programlisting>#include &lt;boost/safe_numerics/safe_integer.hpp&gt;
  97. using namespace boost::numeric;
  98. safe&lt;int&gt; f(safe&lt;int&gt; x, safe&lt;int&gt; y){
  99. return x + y; // throw exception if correct result cannot be returned
  100. }
  101. </programlisting>
  102. <para><note>
  103. <para>Library code in this document resides in the namespace
  104. <code>boost::numeric</code>. This namespace has generally been
  105. eliminated from text, code and examples in order to improve
  106. readability of the text.</para>
  107. </note>The addition expression is checked at runtime or (if possible) at
  108. compile time to trap any possible errors resulting in incorrect arithmetic
  109. behavior. Arithmetic expressions will not produce an erroneous result.
  110. Instead, one and only one of the following is guaranteed to occur.</para>
  111. <para><itemizedlist>
  112. <listitem>
  113. <para>the expression will yield the correct mathematical
  114. result</para>
  115. </listitem>
  116. <listitem>
  117. <para>the expression will emit a compilation error.</para>
  118. </listitem>
  119. <listitem>
  120. <para>the expression will invoke a runtime exception.</para>
  121. </listitem>
  122. </itemizedlist></para>
  123. <para>In other words, the <emphasis role="bold">library absolutely
  124. guarantees that no integer arithmetic expression will yield incorrect
  125. results</emphasis>.</para>
  126. </section>
  127. <section id="safe_numerics.introduction.implementation">
  128. <title>How It Works</title>
  129. <para>The library implements special versions of <code>int</code>,
  130. <code>unsigned</code>, etc. Named <code>safe&lt;int&gt;</code>,
  131. <code>safe&lt;unsigned int&gt;</code> etc. These behave exactly like the
  132. underlying types <emphasis role="bold">except</emphasis> that expressions
  133. using these types fulfill the above guarantee. These "safe" types are
  134. meant to be "drop-in" replacements for the built-in types of the same
  135. name. So things which are legal - such as assignment of a
  136. <code>signed</code> to <code>unsigned</code> value - are not trapped at
  137. compile time as they are legal C/C++ code. Instead, they are checked at
  138. runtime to trap the case where this (legal) operation would lead to an
  139. arithmetically incorrect result.</para>
  140. <para>Note that the library addresses arithmetical errors generated by
  141. straightforward C/C++ expressions. Some of these arithmetic errors are
  142. defined as conforming to the C/C++ standards while others are not. So
  143. characterizing this library as only addressing undefined behavior of C/C++
  144. numeric expressions would be misleading.</para>
  145. <para>Facilities particular to C++14 are employed to minimize any runtime
  146. overhead. In many cases there is no runtime overhead at all. In other
  147. cases, a program using the library can be slightly altered to achieve the
  148. above guarantee without any runtime overhead.</para>
  149. </section>
  150. <section id="safe_numerics.introduction.additional_features">
  151. <title>Additional Features</title>
  152. <para>Operation of safe types is determined by template parameters which
  153. specify a pair of <link linkend="safe_numerics.promotion_policies">policy
  154. classes</link> which specify the behavior for type promotion and error
  155. handling. In addition to the usage serving as a drop-in replacement for
  156. standard integer types, users of the library can:</para>
  157. <para><itemizedlist>
  158. <listitem>
  159. <para>Select or define an exception policy class to specify handling
  160. of exceptions.<itemizedlist>
  161. <listitem>
  162. <para>Throw exception on runtime, trap at compile time if
  163. possible.</para>
  164. </listitem>
  165. <listitem>
  166. <para>Trap at compile time all operations which could possibly
  167. fail at runtime.</para>
  168. </listitem>
  169. <listitem>
  170. <para>Specify custom functions which should be called in case
  171. errors are detected at runtime.</para>
  172. </listitem>
  173. </itemizedlist></para>
  174. </listitem>
  175. <listitem>
  176. <para>Select or define a promotion policy class to alter the C/C++
  177. type promotion rules. This can be used to <itemizedlist>
  178. <listitem>
  179. <para>Use C/C++ native type promotion rules so that, except
  180. for throwing/trapping of exceptions on operations resulting in
  181. incorrect arithmetic behavior, programs will operate
  182. identically when using/not using safe types. This might be
  183. used if safe types are only enabled during debug and
  184. testing.</para>
  185. </listitem>
  186. <listitem>
  187. <para>Replace C/C++ native promotion rules with ones which are
  188. arithmetically equivalent but minimize the need for runtime
  189. checking of arithmetic results. Such a policy will effectively
  190. change the semantics of a C++ program. It's not really C++ any
  191. more. The program cannot be expected to function the same as
  192. when normal integer types are used.</para>
  193. </listitem>
  194. <listitem>
  195. <para>Replace C/C++ native promotion rules with ones which
  196. emulate other machine architectures. This is designed to
  197. permit the testing of C/C++ code destined to be run on another
  198. machine on one's development platform. Such a situation often
  199. occurs while developing code for embedded systems.</para>
  200. </listitem>
  201. </itemizedlist></para>
  202. </listitem>
  203. <listitem>
  204. <para>Enforce other program requirements using bounded integer
  205. types. The library includes the types for ranges and literals.
  206. Operations which violate these requirements will be trapped at
  207. either compile time or runtime and not silently return invalid
  208. values. These types can be used to improve program correctness and
  209. performance.</para>
  210. </listitem>
  211. </itemizedlist></para>
  212. </section>
  213. <section id="safe_numerics.introduction.requirements">
  214. <title>Requirements</title>
  215. <para>This library is composed entirely of C++ Headers. It requires a
  216. compiler compatible with the C++14 standard.</para>
  217. <para>The following Boost Libraries must be installed in order to use this
  218. library</para>
  219. <para><itemizedlist>
  220. <listitem>
  221. <para>mp11</para>
  222. </listitem>
  223. <listitem>
  224. <para>integer</para>
  225. </listitem>
  226. <listitem>
  227. <para>config</para>
  228. </listitem>
  229. <listitem>
  230. <para>tribool</para>
  231. </listitem>
  232. <listitem>
  233. <para>enable_if</para>
  234. </listitem>
  235. </itemizedlist>The Safe Numerics library is delivered with an exhaustive
  236. suite of test programs.</para>
  237. </section>
  238. <section id="safe_numerics.introduction.scope">
  239. <title>Scope</title>
  240. <para>This library currently applies only to built-in integer types.
  241. Analogous issues arise for floating point types but they are not currently
  242. addressed by this version of the library. User or library defined types
  243. such as arbitrary precision integers can also have this problem. Extension
  244. of this library to these other types is not currently under development
  245. but may be addressed in the future. This is one reason why the library
  246. name is "safe numeric" rather than "safe integer" library.</para>
  247. </section>
  248. </section>