-
Notifications
You must be signed in to change notification settings - Fork 0
/
c-pitfall-unsigned.html
270 lines (191 loc) · 20.4 KB
/
c-pitfall-unsigned.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<!-- Mirrored from soundsoftware.ac.uk/c-pitfall-unsigned by HTTrack Website Copier/3.x [XR&CO'2014], Tue, 01 Aug 2017 18:44:18 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Pitfalls in C and C++: Unsigned types | Sound Software .ac.uk</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="sites/soundsoftware.ac.uk/files/favicon.png" type="image/x-icon" />
<link type="text/css" rel="stylesheet" media="all" href="sites/soundsoftware.ac.uk/files/css/css_96672be50d2b2bf1d283b8d9324e7be5.css" />
<link type="text/css" rel="stylesheet" media="print" href="sites/soundsoftware.ac.uk/files/css/css_9cb387b73479bd590fedb6ec230dc035.css" />
<!--[if IE]>
<link type="text/css" rel="stylesheet" media="all" href="/sites/all/themes/zen/zen/ie.css?j" />
<![endif]-->
<script type="text/javascript" src="sites/soundsoftware.ac.uk/files/js/js_5be44a4bd1f33d1988c9f73fe4b7f463.js"></script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
jQuery.extend(Drupal.settings, { "basePath": "/", "googleanalytics": { "trackOutbound": 1, "trackMailto": 1, "trackDownload": 1, "trackDownloadExtensions": "7z|aac|arc|arj|asf|asx|avi|bin|csv|doc(x|m)?|dot(x|m)?|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|msi|msp|pdf|phps|png|ppt(x|m)?|pot(x|m)?|pps(x|m)?|ppam|sld(x|m)?|thmx|qtm?|ra(m|r)?|sea|sit|tar|tgz|torrent|txt|wav|wma|wmv|wpd|xls(x|m|b)?|xlt(x|m)|xlam|xml|z|zip" } });
//--><!]]>
</script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
(function(i,s,o,g,r,a,m){i["GoogleAnalyticsObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,"script","http://www.google-analytics.com/analytics.js","ga");ga("create", "UA-18698611-1", { "cookieDomain": "auto" });ga("set", "anonymizeIp", true);ga("send", "pageview");
//--><!]]>
</script>
<link rel="alternate" type="application/rss+xml" title="Subscribe" href="rss.xml" />
<meta name="google-site-verification" content="gKmyKIK_OFaFd5f07E7wIMUM59VMmUIZc7xa3qKgFEo" />
</head>
<body class="not-front not-logged-in node-type-story two-sidebars page-c-pitfall-unsigned section-c-pitfall-unsigned">
<div id="page"><div id="page-inner">
<a name="navigation-top" id="navigation-top"></a>
<div id="skip-to-nav"><a href="#navigation">Skip to Navigation</a></div>
<div id="header"><div id="header-inner" class="clear-block">
<div id="logo-title">
<a href="index.html" title="Home" rel="home">
<div id="site-name"><strong>
Sound Software .ac.uk </strong></div>
</a>
</div> <!-- /#logo-title -->
</div></div> <!-- /#header-inner, /#header -->
<div id="main"><div id="main-inner" class="clear-block with-navbar">
<div id="content"><div id="content-inner">
<div id="content-header">
<h1 class="title">Pitfalls in C and C++: Unsigned types</h1>
</div> <!-- /#content-header -->
<div id="content-area">
<div id="node-90" class="node node-type-story"><div class="node-inner">
<div class="content">
<p><i>Part of an occasional series of posts discussing sometimes maddening aspects of sound and music research work and software development</i></p>
<p>Despite the antiquity of the C and C++ programming languages and the relative difficulty of writing reliable code in either, audio researchers sometimes have a need to write or port code into these languages—either for speed, or for compatibility with a wider ecosystem such as <a href="http://vamp-plugins.org/">Vamp plugins</a>.</p>
<p>Here we talk about one of the common pitfalls in this process: unsigned types.</p>
<p>C and C++ are unusual amongst languages nowadays in making a distinction between signed and unsigned integers. An int is signed by default, meaning it can represent both positive and negative values. An unsigned is an integer that can never be negative. If you take an unsigned 0 and subtract 1 from it, the result wraps around, leaving a very large number (2^32-1 with the typical 32-bit integer size).</p>
<p>Intuitively the two types seem to map fairly reasonably to mathematical notions of integers and natural numbers, leading many programmers to choose unsigned types for any values that "feel" like they should never be negative, such as loop indices or measurements of size. Unfortunately, this is not a reliable intuition.</p>
<h3>When should I use unsigned?</h3>
<p><b>Never.</b> There, that was easy—can we go home now?</p>
<p>Of course, it's not quite that simple.</p>
<p>You should use unsigned values whenever you are dealing with bit values, i.e. direct representations of the contents of memory; or when doing manipulations such as bit masking or shifting on data, for example when writing low-level code to read binary file formats such as audio files; or if you happen to be doing work such as embedded programming where type sizes and alignments really matter.</p>
<p>But stick to plain signed integers otherwise. You'll avoid a whole class of common problems.</p>
<h3>Why?</h3>
<p>The single most common cause of errors in C and C++ audio analysis code I get to review is arithmetic underflow on unsigned int.</p>
<p>Here's a typical example.</p>
<pre>
for (unsigned i = 0; i < nlengths; i++) {
unsigned candidates = total - lengths[i] + 1;
for (unsigned j = 0; j < candidates; j++) {
// use j as an array index
</pre><p>
When I ran this code on a very short audio file, total came out as zero and lengths[i] as 28. The calculation of candidates then underflowed, coming out somewhere in the region of four billion.</p>
<p>But if you simply replace unsigned by int throughout, including in the definitions of the lengths array and total count, the code magically becomes correct.</p>
<p>You could say that the programmer should simply have checked that total was big enough before doing the calculation. Well, yes—but they didn't, and the programmer of this example was very far from stupid and inexperienced. This kind of thing happens all the time: I've done it myself and I'm sure most other C and C++ programmers have too. (Though some of them probably don't know it yet!)</p>
<p>And there is no <i>advantage</i> to using unsigneds here. There's nothing about a 32-bit unsigned integer type that makes it intrinsically appropriate for representing loop indices or counts of things. It doesn't model the behaviour of natural numbers any better than a signed int does. Natural numbers don't wrap around!</p>
<p>Things would be different if int and unsigned were truly separate types, so that the extra information in the type name actually helped the compiler ensure that the types were right. But that isn't the case: if you write a function with a signature like</p>
<pre>
void f(unsigned int count) { }
</pre><p>and call it with</p>
<pre>
f(-1);
</pre><p>the compiler will just pass some gigantic number into the function without even a warning. So you can't use unsigned to enforce any useful restrictions either.</p>
<h3>Common counterarguments</h3>
<p><i>“You have to deal with unsigneds anyway, because library functions use them.”</i></p>
<p>This is probably the strongest counterargument. Every time you call std::vector::size(), you get an unsigned value back. Code like</p>
<pre>
if (i < v.size()-1) {
</pre><p>will underflow if v is empty. So I'm afraid you can't just forget about the question, even if you never use unsigned yourself.</p>
<p><i>“If the standard libraries use unsigned, doesn't that mean it's good practice?”</i></p>
<p>There are plenty of situations in which using unsigned <i>is</i> good practice: much embedded or low-level software development for example. The standard library doesn't guess what you're up to, instead it just uses the type most closely aligned with the category of operation it's doing. And when it's dealing with sizes and allocations, that category is "memory", which means it uses unsigned values.</p>
<p>Note that there are also well-designed libraries that <i>avoid</i> unsigned types for sizes and indices (for example <a href="http://qt-project.org/doc/qt-4.8/QList.html">Qt4</a>). And of course, many languages more recent than C have been designed without unsigned types at all.</p>
<p><i>“Unsigned has a bigger range.”</i></p>
<p>Only a bit bigger. If that's an issue, you probably need a 64-bit type anyway.</p>
<p><i>“Unsigned overflow and arithmetic is better-defined.”</i></p>
<p>True. In particular, signed overflow and underflow are completely undefined in C (INT_MAX + 1 could be anything); modular arithmetic on negative numbers is implementation dependent; and so is bit shifting of signed integers. My contention is that these limitations cause fewer problems in practice than unintended unsigned underflow. A large fraction of the code I see in day-to-day work could be made more reliable by globally replacing “unsigned” or “unsigned int” with “int” with no side-effects at all.</p>
<p><i>“Unsigneds are faster.”</i></p>
<p>This idea is explored <a href="http://embeddedgurus.com/stack-overflow/2009/07/efficient-c-tips-10-use-unsigned-integers/">here</a>, for example, in an article aimed at embedded software developers. In a workstation environment, however, the opposite is often true. Precisely because signed overflow is undefined, compilers are allowed to make optimisations that assume that signed integer cannot overflow, and this enables a whole class of loop and vector optimisations that simply aren't possible with unsigned integers. Not that it'll make much difference to your code either way, but it's a nice thought.</p>
<h3>Summary</h3>
<ul>
<li><b>Avoid using unsigned ints in C and C++</b> unless you're dealing with raw memory contents or performing bit manipulations like shifting or masking.</li>
<li><b>Turn on compiler warnings</b>, so that the compiler can tell you if you're mixing signeds with unsigned values from library code: resolve those cases by <b>casting the unsigneds to signed integers</b>, not vice versa.</li>
</ul>
<p>—<i>Chris Cannam</i></p>
</div>
<ul class="links inline"><li class="comment_forbidden first last"></li>
</ul>
</div></div> <!-- /node-inner, /node -->
</div>
</div></div> <!-- /#content-inner, /#content -->
<div id="navbar"><div id="navbar-inner" class="clear-block region region-navbar">
<a name="navigation" id="navigation"></a>
<div id="primary" class="clear-block">
<!-- <ul class="links"><li class="menu-245 first"><a href="/resources" title="">Resources</a></li>
<li class="menu-117"><a href="/activities" title="Activities">Activities</a></li>
<li class="menu-116 last"><a href="/aboutus" title="">About</a></li>
</ul> -->
<ul class="menu"><li class="expanded first"><a href="resources.html" title="">Resources</a><ul class="menu"><li class="leaf first"><a href="tools.html" title="Tools and Facilities">Tools</a></li>
<li class="leaf"><a href="handouts-guides.html" title="Printable Handouts and Guides">Handouts/Guides</a></li>
<li class="leaf"><a href="videos.html" title="Videos and slide presentations">Videos/Slides</a></li>
<li class="leaf"><a href="programming-examples.html" title="">Code examples</a></li>
<li class="leaf last"><a href="archive.html" title="">Blog archive</a></li>
</ul></li>
<li class="expanded"><a href="activities.html" title="Activities">Activities</a><ul class="menu"><li class="leaf first"><a href="rr-prize.html" title="Reproducible Research Prizes">Reproducible Research Prizes</a></li>
<li class="leaf"><a href="soundsoftware2014.html" title="SoundSoftware 2014: Third Workshop on Software and Data for Audio and Music Research">SoundSoftware 2014</a></li>
<li class="leaf"><a href="soundsoftware2013.html" title="SoundSoftware 2013: Workshop on Software and Data for Audio and Music Research">SoundSoftware 2013</a></li>
<li class="leaf last"><a href="soundsoftware2012.html" title="SoundSoftware 2012: Workshop on Software and Data for Audio and Music Research">SoundSoftware 2012</a></li>
</ul></li>
<li class="expanded last"><a href="aboutus.html" title="">About</a><ul class="menu"><li class="leaf first"><a href="overview.html" title="Our aim">Our aim</a></li>
<li class="leaf"><a href="aboutus.html" title="">Who we are</a></li>
<li class="leaf last"><a href="contact.html" title="Contact us">Contact us</a></li>
</ul></li>
</ul> </div> <!-- /#primary -->
</div></div> <!-- /#navbar-inner, /#navbar -->
<div id="sidebar-left"><div id="sidebar-left-inner" class="region region-left">
<div id="block-block-9" class="block block-block region-odd odd region-count-1 count-1"><div class="block-inner">
<div class="content">
<p><a class="twitter-timeline" href="https://twitter.com/soundsoftwareuk" data-widget-id="368361225786126337" height="500" width="auto" data-chrome="nofooter noborders transparent" data-border-color="#3e442c" data-link-color="#be5600">Tweets by @soundsoftwareuk</a></p>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> </div>
</div></div> <!-- /block-inner, /block -->
<div id="block-views-recent_stories-block_1" class="block block-views region-even even region-count-2 count-2"><div class="block-inner">
<h2 class="title">Recent notes</h2>
<div class="content">
<div class="view view-recent-stories view-id-recent_stories view-display-id-block_1 recentnotes view-dom-id-5ccb2f8dff583da998247b70a6ed5fd2">
<div class="view-content">
<div class="views-row views-row-1 views-row-odd views-row-first">
<div class="views-field views-field-title"> <span class="field-content"><a href="rr-prize-mlsp-2014-winners.html">MLSP Prizes for Reproducibility: Winners announced!</a></span> </div>
<div class="views-field views-field-teaser"> <div class="field-content"><p>Announcing the winners of the MLSP 2014 and SoundSoftware.ac.uk Prizes for Reproducibility in Signal Processing, organised by SoundSoftware.ac.uk in conjuction with the IEEE Signal Processing Society for the 2014 IEEE International Workshop on Machine Learning for Signal Processing.</p>
</div> </div> </div>
<div class="views-row views-row-2 views-row-even">
<div class="views-field views-field-title"> <span class="field-content"><a href="soundsoftware2014-videos-available.html">SoundSoftware 2014: Videos now available!</a></span> </div>
<div class="views-field views-field-teaser"> <div class="field-content"><p>The SoundSoftware 2014 workshop, our third annual workshop on software and data in audio and music research, was just as enjoyable as the previous two. Because so much research in this field ends up being expressed through software, a software workshop turns out to be all about the means by which research becomes useful and relevant to people other than the original researchers—fertile ground for interesting and thought-provoking talks.</p>
<p>The workshop videos are now available online at <a href="soundsoftware2014.html" title="http://soundsoftware.ac.uk/soundsoftware2014">http://soundsoftware.ac.uk/soundsoftware2014</a>, so if you weren't able to make it in person, catch up here!</p>
</div> </div> </div>
<div class="views-row views-row-3 views-row-odd views-row-last">
<div class="views-field views-field-title"> <span class="field-content"><a href="soundsoftware2014-registernow.html">Register now for the SoundSoftware Third Workshop!</a></span> </div>
<div class="views-field views-field-teaser"> <div class="field-content"><p>Our third annual one-day workshop on Software and Data for Audio and Music Research takes place on the 8th of July 2014 at Queen Mary, University of London. The workshop includes talks on issues such as robust software development for audio and music research, reproducible research in general, management of research data, and open access. <a href="soundsoftware2014.html">Read more here</a>, clear your calendar, and register now!</p>
</div> </div> </div>
</div>
</div> </div>
</div></div> <!-- /block-inner, /block -->
</div></div> <!-- /#sidebar-left-inner, /#sidebar-left -->
<div id="sidebar-right"><div id="sidebar-right-inner" class="region region-right">
<div id="block-search-0" class="block block-search region-odd odd region-count-1 count-3"><div class="block-inner">
<div class="content">
<form action="http://soundsoftware.ac.uk/c-pitfall-unsigned" accept-charset="UTF-8" method="post" id="search-block-form">
<div><div class="container-inline">
<div class="form-item" id="edit-search-block-form-1-wrapper">
<label for="edit-search-block-form-1">Search this site: </label>
<input type="text" maxlength="128" name="search_block_form" id="edit-search-block-form-1" size="15" value="" title="Enter the terms you wish to search for." class="form-text" />
</div>
<input type="submit" name="op" id="edit-submit" value="Search" class="form-submit" />
<input type="hidden" name="form_build_id" id="form-GIXF46JdtAAuj1Lkmdnr1r6sV9SsaXJePDEuVDnIP0U" value="form-GIXF46JdtAAuj1Lkmdnr1r6sV9SsaXJePDEuVDnIP0U" />
<input type="hidden" name="form_id" id="edit-search-block-form" value="search_block_form" />
</div>
</div></form>
</div>
</div></div> <!-- /block-inner, /block -->
<div id="block-block-8" class="block block-block region-even even region-count-2 count-4"><div class="block-inner">
<div class="content">
<p><a href="archive.html">Archive</a></p>
</div>
</div></div> <!-- /block-inner, /block -->
</div></div> <!-- /#sidebar-right-inner, /#sidebar-right -->
</div></div> <!-- /#main-inner, /#main -->
<div id="footer"><div id="footer-inner" class="region region-footer">
<div id="block-block-1" class="block block-block region-odd odd region-count-1 count-5"><div class="block-inner">
<div class="content">
<p><span class="f-left"><a rel="license" href="http://creativecommons.org/licenses/by-nc/3.0/" target="_blank"><img alt="Creative Commons Licence" style="margin-top: 2px; margin-right: 4px; border-width:0; float:left; " src="http://i.creativecommons.org/l/by-nc/3.0/88x31.png" /></a><span>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc/3.0/">Creative Commons Attribution-NonCommercial 3.0 License</a>.<br /> © 2011 Queen Mary University of London </span></span><span class="f-right"><a rel="rss" href="rss.xml" target="_blank"><img alt="Subscribe to this site's RSS feed" style="margin-top: -2px; margin-right: 4px; border-width:0; float:left; " src="sites/all/themes/soundsoftware/socialnet_icons/rss_16.png" /></a><a rel="twitter" href="http://twitter.com/soundsoftwareuk" target="_blank"><img alt="Follow us on Twitter!" style="margin-top: -2px; margin-right: 4px; border-width:0; float:left; " src="sites/all/themes/soundsoftware/socialnet_icons/twitter_16.png" /></a><a rel="linkedin group" href="http://www.linkedin.com/groups?mostPopular=&gid=3472350" target="_blank"><img alt="Join or follow our LinkedIn group" style="margin-top: -2px; margin-right: 4px; border-width:0; float:left; " src="sites/all/themes/soundsoftware/socialnet_icons/linkedin_16.png" /></a></span></p>
</div>
</div></div> <!-- /block-inner, /block -->
</div></div> <!-- /#footer-inner, /#footer -->
</div></div> <!-- /#page-inner, /#page -->
</body>
<!-- Mirrored from soundsoftware.ac.uk/c-pitfall-unsigned by HTTrack Website Copier/3.x [XR&CO'2014], Tue, 01 Aug 2017 18:44:18 GMT -->
</html>