1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> 4<title>Arithmetic on Unsigned Integers 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="2.html" title="Arithmetic Operations Can Overflow Silently"> 10<link rel="next" href="4.html" title="Implicit Conversions Can Lead to Erroneous Results"> 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="2.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="4.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.3"></a>Arithmetic on Unsigned Integers Can Yield Incorrect Results</h3></div></div></div> 23<p>Subtracting two unsigned values of the same size will result in an 24 unsigned value. If the first operand is less than the second the result 25 will be arithmetically in correct. But if the size of the unsigned types 26 is less than that of an <code class="computeroutput">unsigned int</code>, C/C++ will promote the 27 types to <code class="computeroutput">signed int</code> before subtracting resulting in an 28 correct result. In either case, there is no indication of an error. 29 Somehow, the programmer is expected to avoid this behavior. Advice usually 30 takes the form of "Don't use unsigned integers for arithmetic". This is 31 well and good, but often not practical. C/C++ itself uses unsigned for 32 <code class="computeroutput">sizeof(T)</code> which is then used by users in arithmetic.</p> 33<p>This program demonstrates this problem. The solution is to replace 34 instances of built in integer types with corresponding safe types.</p> 35<pre class="programlisting"><p><span class="comment">// Copyright (c) 2018 Robert Ramey</span> 36<span class="comment">//</span> 37<span class="comment">// Distributed under the Boost Software License, Version 1.0. (See</span> 38<span class="comment">// accompanying file LICENSE_1_0.txt or copy at</span> 39<span class="comment">// http://www.boost.org/LICENSE_1_0.txt)</span> 40 41<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 42 43<span class="preprocessor">#include</span> <span class="special"><</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">></span> 44 45<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> 46 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"example 8:"</span><span class="special">;</span> 47 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"undetected erroneous expression evaluation"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 48 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Not using safe numerics"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 49 <span class="keyword">try</span><span class="special">{</span> 50 <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">127</span><span class="special">;</span> 51 <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">y</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span> 52 <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">z</span><span class="special">;</span> 53 <span class="comment">// this produces an invalid result !</span> 54 <span class="identifier">z</span> <span class="special">=</span> <span class="identifier">y</span> <span class="special">-</span> <span class="identifier">x</span><span class="special">;</span> 55 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"error NOT detected!"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 56 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">z</span> <span class="special"><<</span> <span class="string">" != "</span> <span class="special"><<</span> <span class="identifier">y</span> <span class="special"><<</span> <span class="string">" - "</span> <span class="special"><<</span> <span class="identifier">x</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 57 <span class="special">}</span> 58 <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">&</span><span class="special">)</span><span class="special">{</span> 59 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"error detected!"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 60 <span class="special">}</span> 61 <span class="comment">// solution: replace int with safe<int></span> 62 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Using safe numerics"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 63 <span class="keyword">try</span><span class="special">{</span> 64 <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> 65 <span class="identifier">safe</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">127</span><span class="special">;</span> 66 <span class="identifier">safe</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">y</span> <span class="special">=</span> <span class="number">2</span><span class="special">;</span> 67 <span class="identifier">safe</span><span class="special"><</span><span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">z</span><span class="special">;</span> 68 <span class="comment">// rather than producing an invalid result an exception is thrown</span> 69 <span class="identifier">z</span> <span class="special">=</span> <span class="identifier">y</span> <span class="special">-</span> <span class="identifier">x</span><span class="special">;</span> 70 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"error NOT detected!"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 71 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">z</span> <span class="special"><<</span> <span class="string">" != "</span> <span class="special"><<</span> <span class="identifier">y</span> <span class="special"><<</span> <span class="string">" - "</span> <span class="special"><<</span> <span class="identifier">x</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 72 <span class="special">}</span> 73 <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">&</span> <span class="identifier">e</span><span class="special">)</span><span class="special">{</span> 74 <span class="comment">// which we can catch here</span> 75 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"error detected:"</span> <span class="special"><<</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"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 76 <span class="special">}</span> 77 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 78<span class="special">}</span> 79</p></pre> 80<pre class="screen">example 8:undetected erroneous expression evaluation 81Not using safe numerics 82error NOT detected! 834294967171 != 2 - 127 84Using safe numerics 85error detected:subtraction result cannot be negative: negative overflow error 86Program ended with exit code: 0</pre> 87</div> 88<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 89<td align="left"></td> 90<td align="right"><div class="copyright-footer">Copyright © 2012-2018 Robert Ramey<p><a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">Subject to Boost 91 Software License</a></p> 92</div></td> 93</tr></table> 94<hr> 95<div class="spirit-nav"> 96<a accesskey="p" href="2.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="4.html"><img src="../images/next.png" alt="Next"></a> 97</div> 98</body> 99</html> 100