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