• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4<title>Arithmetic Expressions Can Yield Incorrect Results</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="../tutorial.html" title="Tutorial and Motivating Examples">
10<link rel="next" href="2.html" title="Arithmetic Operations Can Overflow Silently">
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="../tutorial.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="2.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.1"></a>Arithmetic Expressions Can Yield Incorrect Results</h3></div></div></div>
23<p>When some operation on signed integer types results in a result
24    which exceeds the capacity of a data variable to hold it, the result is
25    undefined. In the case of unsigned integer types a similar situation
26    results in a value wrap as per modulo arithmetic. In either case the
27    result is different than in integer number arithmetic in the mathematical
28    sense. This is called "overflow". Since word size can differ between
29    machines, code which produces mathematically correct results in one set of
30    circumstances may fail when re-compiled on a machine with different
31    hardware. When this occurs, most C++ programs will continue to execute
32    with no indication that the results are wrong. It is the programmer's
33    responsibility to ensure such undefined behavior is avoided.</p>
34<p>This program demonstrates this problem. The solution is to replace
35    instances of built in integer types with corresponding safe types.</p>
36<pre class="programlisting"><span class="comment">//  Copyright (c) 2018 Robert Ramey</span>
37<span class="comment">//</span>
38<span class="comment">// Distributed under the Boost Software License, Version 1.0. (See</span>
39<span class="comment">// accompanying file LICENSE_1_0.txt or copy at</span>
40<span class="comment">// http://www.boost.org/LICENSE_1_0.txt)</span>
41
42<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
43
44<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</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
45
46<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>
47    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"example 1:"</span><span class="special">;</span>
48    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"undetected erroneous expression evaluation"</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>
49    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Not using safe numerics"</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>
50    <span class="keyword">try</span><span class="special">{</span>
51        <span class="identifier">std</span><span class="special">::</span><span class="identifier">int8_t</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">127</span><span class="special">;</span>
52        <span class="identifier">std</span><span class="special">::</span><span class="identifier">int8_t</span> <span class="identifier">y</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
53        <span class="identifier">std</span><span class="special">::</span><span class="identifier">int8_t</span> <span class="identifier">z</span><span class="special">;</span>
54        <span class="comment">// this produces an invalid result !</span>
55        <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>
56        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"error NOT detected!"</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>
57        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="identifier">z</span> <span class="special">&lt;&lt;</span> <span class="string">" != "</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="identifier">x</span> <span class="special">&lt;&lt;</span> <span class="string">" + "</span> <span class="special">&lt;&lt;</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="identifier">y</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>
58    <span class="special">}</span>
59    <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">&amp;</span><span class="special">)</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">"error detected!"</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="special">}</span>
62    <span class="comment">// solution: replace int with safe&lt;int&gt;</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">"Using safe numerics"</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">try</span><span class="special">{</span>
65        <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>
66        <span class="identifier">safe</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">int8_t</span><span class="special">&gt;</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">INT_MAX</span><span class="special">;</span>
67        <span class="identifier">safe</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">int8_t</span><span class="special">&gt;</span> <span class="identifier">y</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span>
68        <span class="identifier">safe</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">int8_t</span><span class="special">&gt;</span> <span class="identifier">z</span><span class="special">;</span>
69        <span class="comment">// rather than producing an invalid result an exception is thrown</span>
70        <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>
71    <span class="special">}</span>
72    <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">&amp;</span> <span class="identifier">e</span><span class="special">)</span><span class="special">{</span>
73        <span class="comment">// which we can catch here</span>
74        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"error detected:"</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">(</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>
75    <span class="special">}</span>
76    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
77<span class="special">}</span>
78</pre>
79<pre class="screen">example 1:undetected erroneous expression evaluation
80Not using safe numerics
81error NOT detected!
82-127 != 127 + 2
83Using safe numerics
84error detected:converted signed value too large: positive overflow error
85Program ended with exit code: 0</pre>
86</div>
87<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
88<td align="left"></td>
89<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
90      Software License</a></p>
91</div></td>
92</tr></table>
93<hr>
94<div class="spirit-nav">
95<a accesskey="p" href="../tutorial.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="2.html"><img src="../images/next.png" alt="Next"></a>
96</div>
97</body>
98</html>
99