1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
4<section id="safe_numerics.rationale">
5  <title>Rationale and FAQ</title>
6
7  <qandaset defaultlabel="number">
8    <qandaentry>
9      <question>
10        <para>Is this really necessary? If I'm writing the program with the
11        requisite care and competence, problems noted in the introduction will
12        never arise. Should they arise, they should be fixed "at the source"
13        and not with a "band aid" to cover up bad practice.</para>
14      </question>
15
16      <answer>
17        <para>This surprised me when it was first raised. But some of the
18        feedback I've received makes me think that it's a widely held view.
19        The best answer is to consider the examples in the <link
20        linkend="safe_numerics.tutorial">Tutorials and Motivating
21        Examples</link> section of the library documentation. I believe they
22        convincingly demonstrate that any program which does not use this
23        library must be assumed to contain arithmetic errors.</para>
24      </answer>
25    </qandaentry>
26
27    <qandaentry>
28      <question>
29        <para>Can safe types be used as drop-in replacements for built-in
30        types?</para>
31      </question>
32
33      <answer>
34        <para>Almost. Replacing all built-in types with their safe
35        counterparts should result in a program that will compile and run as
36        expected. Occasionally compile time errors will occur and adjustments
37        to the source code will be required. Typically these will result in
38        code which is more correct.</para>
39      </answer>
40    </qandaentry>
41
42    <qandaentry>
43      <question>
44        <para>Why are there special types for literal such as
45        <code>safe_signed_literal&lt;42&gt;</code>? Why not just use
46        std::integral_const&lt;int, 42&gt;?</para>
47      </question>
48
49      <answer>
50        <para>By defining our own "special" type we can simplify the
51        interface. Using <code>std::integral_const</code> requires one to
52        specify both the type <emphasis>and</emphasis> the value. Using
53        <code>safe_signed_literal&lt;42&gt;</code> doesn't require a parameter
54        for the type. So the library can select the best type to hold the
55        specified value. It also means that one won't have the opportunity to
56        specify a type-value pair which are inconsistent.</para>
57      </answer>
58    </qandaentry>
59
60    <qandaentry>
61      <question>
62        <para>Why is safe...literal needed at all? What's the matter with
63        <code>const safe&lt;int&gt;(42)</code>?</para>
64      </question>
65
66      <answer>
67        <para><code>const safe&lt;int&gt;(42)</code> looks like it might be
68        what we want: An immutable value which invokes the "safe" operators
69        when used in an expression. But there is one problem. The
70        <code>std::numeric_limits&lt;safe&lt;int&gt;&gt;</code> is a range
71        from INTMIN to INTMAX even though the value is fixed to 42 at compile
72        time. It is this range which is used at compile time to calculate the
73        range of the result of the operation.</para>
74
75        <para>So when an operation is performed, the range of the result is
76        calculated from [INTMIN, INTMAX] rather than from [42,42].</para>
77      </answer>
78    </qandaentry>
79
80    <qandaentry>
81      <question>
82        <para>Are safe type operations <code>constexpr</code>? That is, can
83        they be invoked at compile time?</para>
84      </question>
85
86      <answer>
87        <para>Yes. safe type construction and calculations are all
88        <code>constexpr</code>. Note that to get maximum benefit, you'll have
89        to use <code>safe...literal</code> to specify the primitive values at
90        compile time.</para>
91      </answer>
92    </qandaentry>
93
94    <qandaentry>
95      <question>
96        <para>Why define <link
97        linkend="safe_numerics.safe_literal"><code>safe_literal</code></link>?
98        Isn't it effectively the same as
99        <code>std::integral_constant</code>?</para>
100      </question>
101
102      <answer>
103        <para>Almost, but there are still good reasons to create a different
104        type.<itemizedlist>
105            <listitem>
106              <para><code>std::integral_constant&lt;int, 42&gt;</code>
107              requires specification of type as well as value so it's less
108              convenient than safe_signed_literal which maps to the smallest
109              type required to hold the value.</para>
110            </listitem>
111
112            <listitem>
113              <para><code>std::numeric_limits&lt;std::integral_constant&lt;int,
114              42&gt;&gt;::is_integer</code> returns <code>false</code>. This
115              would complicate implementation of the library</para>
116            </listitem>
117
118            <listitem>
119              <para>type trait <code>is_safe&lt;std::integral_constant&lt;int,
120              42&gt;&gt;</code> would have to be defined to return
121              <code>true</code>.</para>
122            </listitem>
123
124            <listitem>
125              <para>But globally altering the traits of
126              <code>std::integral_constant</code> might have unintended
127              side-effects related to other code. These might well be
128              surprises which are create errors which are hard to find and
129              hard to work around.</para>
130            </listitem>
131          </itemizedlist></para>
132      </answer>
133    </qandaentry>
134
135    <qandaentry>
136      <question>
137        <para>Why is Boost.Convert not used?</para>
138      </question>
139
140      <answer>
141        <para>I couldn't figure out how to use it from the
142        documentation.</para>
143      </answer>
144    </qandaentry>
145
146    <qandaentry>
147      <question>
148        <para>Why is the library named "safe ..." rather than something like
149        "checked ..." ?</para>
150      </question>
151
152      <answer>
153        <para>I used "safe" in large part because this is what has been used
154        by other similar libraries. Maybe a better word might have been
155        "correct" but that would raise similar concerns. I'm not inclined to
156        change this. I've tried to make it clear in the documentation what the
157        problem that the library addressed is.</para>
158      </answer>
159    </qandaentry>
160
161    <qandaentry>
162      <question>
163        <para>Given that the library is called "numerics" why is floating
164        point arithmetic not addressed?</para>
165      </question>
166
167      <answer>
168        <para>Actually, I believe that this can/should be applied to any type
169        T which satisfies the type requirement <code>Numeric</code> type as
170        defined in the documentation. So there should be specializations
171        <code>safe&lt;float&gt;</code> and related types as well as new types
172        like <code>safe&lt;fixed_decimal&gt;</code> etc. But the current
173        version of the library only addresses integer types. Hopefully the
174        library will evolve to match the promise implied by its name.</para>
175      </answer>
176    </qandaentry>
177
178    <qandaentry>
179      <question>
180        <para>Isn't putting a defensive check just before any potential
181        undefined behavior often considered a bad practice?</para>
182      </question>
183
184      <answer>
185        <para>By whom? Is leaving code which can produce incorrect results
186        better? Note that the documentation contains references to various
187        sources which recommend exactly this approach to mitigate the problems
188        created by this C/C++ behavior. See
189        <citation>Seacord</citation></para>
190      </answer>
191    </qandaentry>
192
193    <qandaentry>
194      <question>
195        <para>It looks like the implementation presumes two's complement
196        arithmetic at the hardware level. So this library is not portable -
197        correct? What about other hardware architectures?</para>
198      </question>
199
200      <answer>
201        <para>As far as is known as of this writing, the library does not
202        presume that the underlying hardware is two's complement. However,
203        this has yet to be verified in any rigorous way.</para>
204      </answer>
205    </qandaentry>
206
207    <qandaentry>
208      <question>
209        <para>According to C/C++ standards, <code>unsigned integers</code>
210        cannot overflow - they are modular integers which "wrap around". Yet
211        the safe numerics library detects and traps this behavior as errors.
212        Why is that?</para>
213      </question>
214
215      <answer>
216        <para>The guiding purpose of the library is to trap incorrect
217        arithmetic behavior - not just undefined behavior. Although a savvy
218        user may understand and keep present in his mind that an unsigned
219        integer is really a modular type, the plain reading of an arithmetic
220        expression conveys the idea that all operands are common integers.
221        Also in many cases, <code>unsigned integers</code> are used in cases
222        where modular arithmetic is not intended, such as array indices.
223        Finally, the modulus for such an integer would vary depending upon the
224        machine architecture. For these reasons, in the context of this
225        library, an <code>unsigned integer</code> is considered to be a
226        representation of a subset of integers. Note that this decision is
227        consistent with <citation>INT30-C</citation>, “Ensure that unsigned
228        integer operations do not wrap” in the CERT C Secure Coding Standard
229        <citation>Seacord</citation>.</para>
230      </answer>
231    </qandaentry>
232
233    <qandaentry>
234      <question>
235        <para>Why does the library require C++14?</para>
236      </question>
237
238      <answer>
239        <para>The original version of the library used C++11. Feedback from
240        CPPCon, <ulink url="http://www.blincubator.com">Boost Library
241        Incubator</ulink> and Boost developer's mailing list convinced me that
242        I had to address the issue of run-time penalty much more seriously. I
243        resolved to eliminate or minimize it. This led to more elaborate
244        meta-programming. But this wasn't enough. It became apparent that the
245        only way to really minimize run-time penalty was to implement
246        compile-time integer range arithmetic - a pretty elaborate sub
247        library. By doing range arithmetic at compile-time, I could skip
248        runtime checking on many/most integer operations. While C++11
249        <code>constexpr</code> wasn't quite powerful enough to do the job,
250        C++14 <code>constexpr</code> is. The library currently relies very
251        heavily on C++14 <code>constexpr</code>. I think that those who delve
252        into the library will be very surprised at the extent that minor
253        changes in user code can produce guaranteed correct integer code with
254        zero run-time penalty.</para>
255      </answer>
256    </qandaentry>
257
258    <qandaentry>
259      <question>
260        <para>This is a C++ library - yet you refer to C/C++. Which is
261        it?</para>
262      </question>
263
264      <answer>
265        <para>C++ has evolved way beyond the original C language. But C++ is
266        still (mostly) compatible with C. So most C programs can be compiled
267        with a C++ compiler. The problems of incorrect arithmetic afflict both
268        C and C++. Suppose we have a legacy C program designed for some
269        embedded system.<itemizedlist>
270            <listitem>
271              <para>Replace all <code>int</code> declarations with
272              <code>int16_t</code> and all <code>long</code> declarations with
273              <code>int32_t</code>.</para>
274            </listitem>
275
276            <listitem>
277              <para>Create a file containing something like the following and
278              include it at the beginning of every source file.</para>
279
280              <programlisting>#ifdef TEST
281// using C++ on test platform
282#include  &lt;cstdint&gt;
283#include &lt;boost/numeric/safe_numerics/safe_integer.hpp&gt;
284#include &lt;cpp.hpp&gt;
285using pic16_promotion = boost::numeric::cpp&lt;
286    8,  // char
287    8,  // short
288    8,  // int
289    16, // long
290    32  // long long
291&gt;;
292// define safe types used in the desktop version of the program.
293template &lt;typename T&gt; // T is char, int, etc data type
294using safe_t = boost::numeric::safe&lt;
295    T,
296    pic16_promotion,
297    boost::numeric::default_exception_policy // use for compiling and running tests
298&gt;;
299typedef safe_t&lt;std::int_least16_t&gt; int16_t;
300typedef safe_t&lt;std::int_least32_t&gt; int32_t;
301#else
302/* using C on embedded platform */
303typedef int int_least16_t;
304typedef long int_least16_t;
305#endif
306
307</programlisting>
308            </listitem>
309
310            <listitem>
311              <para>Compile tests on the desktop with a C++14 compiler and
312              with the macro TEST defined.</para>
313            </listitem>
314
315            <listitem>
316              <para>Run the tests and change the code to address any thrown
317              exceptions.</para>
318            </listitem>
319
320            <listitem>
321              <para>Compile for the target C platform with the macro TEST
322              undefined.</para>
323            </listitem>
324          </itemizedlist></para>
325
326        <para>This example illustrates how this library, implemented with
327        C++14 can be useful in the development of correct code for programs
328        written in C.</para>
329      </answer>
330    </qandaentry>
331
332    <qandaentry>
333      <question>
334        <para>Some compilers (including gcc and clang) include builtin
335        functions for checked addition, multiplication, etc. Does this library
336        use these intrinsics?</para>
337      </question>
338
339      <answer>
340        <para>No. I attempted to use these but they are currently not
341        <code>constexpr</code>. So I couldn't use these without breaking
342        <code>constexpr</code> compatibility for the safe numerics
343        primitives.</para>
344      </answer>
345    </qandaentry>
346
347    <qandaentry>
348      <question>
349        <para>Some compilers (including gcc and clang) included a builtin
350        function for detecting constants. This seemed attractive to eliminate
351        the requirement for the safe_literal type. Alas, these builtin
352        functions are defined as macros. Constants passed through functions
353        down into the safe numerics library cannot be detected as constants.
354        So the opportunity to make the library even more efficient by moving
355        more operations to compile time doesn't exist - contrary to my hopes
356        and expections.</para>
357      </question>
358    </qandaentry>
359  </qandaset>
360</section>
361