1<?xml version="1.0" encoding="UTF-8"?> 2<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 3"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"> 4<article> 5 <articleinfo> 6 <abstract> 7 <para><informaltable> 8 <tgroup cols="2"> 9 <colspec colwidth="1*"/> 10 11 <colspec colwidth="2*"/> 12 13 <tbody> 14 <row> 15 <entry>Document number:</entry> 16 17 <entry>P0228R2</entry> 18 </row> 19 20 <row> 21 <entry>Project:</entry> 22 23 <entry>Programming Language C++</entry> 24 </row> 25 26 <row> 27 <entry>Audience:</entry> 28 29 <entry>SG-6</entry> 30 </row> 31 32 <row> 33 <entry>Author:</entry> 34 35 <entry>Robert Ramey</entry> 36 </row> 37 38 <row> 39 <entry>Contact:</entry> 40 41 <entry>ramey@rrsd.com</entry> 42 </row> 43 44 <row> 45 <entry>Date:</entry> 46 47 <entry>2016-02-16</entry> 48 </row> 49 </tbody> 50 </tgroup> 51 </informaltable></para> 52 </abstract> 53 54 <title>A Proposal to Add Safe Integer Types to the Standard 55 Library</title> 56 </articleinfo> 57 58 <section> 59 <title>Motivation</title> 60 61 <para>Arithmetic operations in C++ are NOT guaranteed to yield a correct 62 mathematical result. This feature is inherited from the early days of C. 63 The behavior of <code>int</code>, <code>unsigned int</code> and others 64 were designed to map closely to the underlying hardware. Computer hardware 65 implements these types as a fixed number of bits. When the result of 66 arithmetic operations exceeds this number of bits, the result will not be 67 arithmetically correct. The following example illustrates this 68 problem.</para> 69 70 <programlisting>int f(int x, int y){ 71 // this returns an invalid result for some legal values of x and y ! 72 return x + y; 73} 74</programlisting> 75 </section> 76 77 <section> 78 <title>Impact On the Standard</title> 79 80 <para>This proposal is a pure library extension. It does not require 81 changes to any standard classes, functions or headers. It might benefit 82 from relaxing some of the conditions on aggregate types. It has been 83 implemented in and requires standard C++/14.</para> 84 </section> 85 86 <section> 87 <title>Design Decisions</title> 88 89 <para>The template class is designed to function as closely as possible as 90 a drop-in replacement for corresponding built-in integer types.</para> 91 92 <orderedlist> 93 <listitem> 94 <para>"Drop In Replacement for Any Integer Type"</para> 95 96 <para>The template class is designed to function as closely as 97 possible as a drop-in replacement for corresponding built-in integer 98 types. Ideally, one should be able to just substitute safe<T> 99 for all instances of T in any program and expect it compile and 100 execute as before with no other changes.</para> 101 102 <para>Since C++ permits freely mixing signed and unsigned integer 103 types in expressions, safe versions of these types can also be. This 104 complicates the implementation of the library to significant 105 degree.</para> 106 </listitem> 107 108 <listitem> 109 <para>"Return No Incorrect Results"</para> 110 111 <para>Usage of a safe type in a binary expression is guaranteed to 112 either return an arithmetically correct result or throw a standard 113 exception.</para> 114 </listitem> 115 116 <listitem> 117 <para>"Automatically Inter operate with built-in integer types"</para> 118 119 <para>The usage of a safe type in binary expression "infects" the 120 expression by returning another safe type. This is designed to avoid 121 accidentally losing the safety of the expression.</para> 122 </listitem> 123 124 <listitem> 125 <para>"Uses <limits> instead of type traits"</para> 126 127 <para>Implementation of a library such as this necessarily keeps track 128 of the types of data objects. The most common way to do this is using 129 type_traits such as <code>std::is_integral</code>, 130 <code>std::is_unsigned</code>, <code>std::is_arithmetic</code>, etc. 131 This doesn't work very well for a few reasons:<simplelist> 132 <member>These are defined by the standard to apply only to 133 built-in types. Specializing these traits for new types such as 134 safe<int> would conflict with the standard.</member> 135 </simplelist></para> 136 137 <para><simplelist> 138 <member>We are allowed to create specialization of 139 std::numeric_limits for our own types - including safe<T>. 140 So this works well for us.</member> 141 </simplelist></para> 142 143 <para><simplelist> 144 <member>safe<T> might be implemented in such as way that it 145 would work for unforeseen integer-like types such as "money". 146 Numeric limits has more complete information about these types 147 which might make it easier to extend the library.</member> 148 </simplelist></para> 149 </listitem> 150 151 <listitem> 152 <para>"Performance"</para> 153 154 <para>Performance will depend on the implementation and subject to the 155 constraints above. This design will permit the usage of template 156 meta-programming to eliminate runtime performance penalties in some 157 cases. In the following example, there is no runtime penalty required 158 to guarantee that incorrect results will never be generated.</para> 159 160 <programlisting>#include <cstdint> 161#include <safe> 162 163using namespace std; 164 165int f(safe<int8_t> i){ 166 // C++ promotion rules make overflow on multiplication impossible! 167 // cannot fail on return 168 // zero performance penalty 169 return i * i; 170} 171 172int8_t f(safe<int8_t> i){ 173 // C++ promotion rules make overflow on multiplication impossible! 174 // but result could be truncated on return 175 // so result must be checked at runtime incurring a runtime penalty 176 return i * i; // cannot overflow on multiplication, 177}</programlisting> 178 179 <para>Some processors have the ability to detect erroneous results but 180 the C++ language doesn't include the ability to exploit these 181 features. Implementor's of this library will have the option to 182 exploit these features to diminish or eliminate runtime costs.</para> 183 184 <para>If all else fails and the runtime cost is deemed too large for 185 the program to bear, users will have the option of creating their own 186 aliases for the types the program uses and assign them according to 187 the whether they are building a "Debug" or "Release" version. This is 188 not ideal, but would still be preferable to the current approach which 189 generally consists of ignoring the possibility that C++ numeric 190 operations may produce arithmetically incorrect results.</para> 191 </listitem> 192 193 <listitem> 194 <para>"No Extra Parameters"</para> 195 196 <para>An alternative to this proposal would be a policy based design 197 which would permit users to select or define actions to be taken in 198 the case of errors. This is quite possible and likely useful. However, 199 the simplicity usage of the current proposal is an important feature. 200 So I decided not to include it.</para> 201 </listitem> 202 203 <listitem> 204 <para>"No other safe types"</para> 205 206 <para>Other ideas come to mind such as <code>safe<Min, 207 Max></code>, <code>safe_literal<Value></code>, and others. I 208 excluded these in the spirit of following the controlling purpose of 209 making a "drop in replacement". Once one included these types into a 210 program, they change the semantics of the program so that it's not 211 really C++ any more. There is a place for these ideas, (see below), 212 but I don't think the standard library is that place.</para> 213 </listitem> 214 </orderedlist> 215 </section> 216 217 <section> 218 <title>Existing Implementations</title> 219 220 <para>This proposal is a simpler version / subset of the Safe Numerics 221 library in development by Robert Ramey on the <ulink 222 url="http://rrsd.com/blincubator.com/bi_library/safe-numerics/?gform_post_id=426?">Boost 223 Library Incubator</ulink>. It is compatible with this proposal but it also 224 includes:<simplelist> 225 <member>Policy classes for error handling</member> 226 </simplelist></para> 227 228 <para><simplelist> 229 <member>Policy classes for type promotion. These permit substitution 230 of C++ standard type promotion rules with other ones which can reduce 231 or eliminate the need for runtime error checking code.</member> 232 </simplelist></para> 233 234 <para><simplelist> 235 <member>Other safe types such as safe_integer_range<Min, 236 Max>.</member> 237 </simplelist></para> 238 239 <para><simplelist> 240 <member>Complete documentation including internal operation</member> 241 </simplelist></para> 242 243 <para>Without comment, here are implementations of libraries which are in 244 some way similar to this proposal:<itemizedlist> 245 <listitem> 246 <para><ulink url="https://github.com/RobertLeahy/Safe">Robert Leahy, 247 Safe integer utilities for C++11</ulink></para> 248 </listitem> 249 250 <listitem> 251 <para><ulink url="http://safeint.codeplex.com">David LeBlanc, 252 SafeInt</ulink></para> 253 </listitem> 254 255 <listitem> 256 <para><ulink url="http://safeint.codeplex.com">David Stone, Bounded 257 Integer</ulink></para> 258 </listitem> 259 </itemizedlist></para> 260 </section> 261 262 <section> 263 <title>Technical Specifications</title> 264 265 <section> 266 <title>Type Requirements</title> 267 268 <xi:include href="numeric_concept.xml" xpointer="element(/1)" 269 xmlns:xi="http://www.w3.org/2001/XInclude"/> 270 271 <xi:include href="integer_concept.xml" xpointer="element(/1)" 272 xmlns:xi="http://www.w3.org/2001/XInclude"/> 273 274 <xi:include href="safe_numeric_concept.xml" xpointer="element(/1)" 275 xmlns:xi="http://www.w3.org/2001/XInclude"/> 276 </section> 277 </section> 278 279 <section> 280 <title>Types</title> 281 282 <section id="safe_numerics.safe"> 283 <title>safe<T></title> 284 285 <section> 286 <title>Description</title> 287 288 <para>A <code>safe<T></code> can be used anywhere a type T can 289 be used. Any expression which uses this type is guaranteed to return 290 an arithmetically correct value or trap in some way.</para> 291 </section> 292 293 <section> 294 <title>Notation</title> 295 296 <informaltable> 297 <tgroup cols="2"> 298 <colspec align="left" colwidth="1*"/> 299 300 <colspec align="left" colwidth="10*"/> 301 302 <thead> 303 <row> 304 <entry align="left">Symbol</entry> 305 306 <entry align="left">Description</entry> 307 </row> 308 </thead> 309 310 <tbody> 311 <row> 312 <entry><code>T</code></entry> 313 314 <entry>Underlying type from which a safe type is being 315 derived</entry> 316 </row> 317 </tbody> 318 </tgroup> 319 </informaltable> 320 </section> 321 322 <section> 323 <title>Template Parameters</title> 324 325 <informaltable> 326 <tgroup cols="3"> 327 <colspec colwidth="1*"/> 328 329 <colspec align="left" colwidth="3*"/> 330 331 <colspec align="left" colwidth="7*"/> 332 333 <thead> 334 <row> 335 <entry align="left">Parameter</entry> 336 337 <entry align="left">Type Requirements</entry> 338 339 <entry>Description</entry> 340 </row> 341 </thead> 342 343 <tbody> 344 <row> 345 <entry><code>T</code></entry> 346 347 <entry><ulink 348 url="http://en.cppreference.com/w/cpp/types/is_integral">Integer</ulink></entry> 349 350 <entry><para>The underlying type. Currently only integer types 351 supported</para></entry> 352 </row> 353 </tbody> 354 </tgroup> 355 </informaltable> 356 357 <para>See examples below.</para> 358 </section> 359 360 <section> 361 <title>Model of</title> 362 363 <para><link linkend="safe_numerics.numeric">Integer</link></para> 364 365 <para><link 366 linkend="safe_numerics.safe_numeric_concept">SafeNumeric</link></para> 367 </section> 368 369 <section> 370 <title>Valid Expressions</title> 371 372 <para>Implements all expressions defined by the <link 373 linkend="safe_numerics.safe_numeric_concept">SafeNumeric</link> type 374 requirements.</para> 375 376 <para><code>safe<T></code> is meant to be a "drop-in" 377 replacement of the intrinsic integer types.</para> 378 379 <para>The type of an expression of type safe<T> op safe<U> 380 will be safe<R> where R would be the same as the type of the 381 expression T op U.That is, expressions involving these types will be 382 evaluated into result types which reflect the standard rules for 383 evaluation of C++ expressions. Should it occur that such evaluation 384 cannot return a correct result, an std::exception will be 385 thrown.</para> 386 </section> 387 388 <section> 389 <title>Header</title> 390 391 <para><filename><ulink url="../../include/safe_integer.hpp">#include 392 <safe></ulink></filename></para> 393 </section> 394 395 <section> 396 <title>Example of use</title> 397 398 <para><code>safe<T></code> is meant to be a "drop-in" 399 replacement of the intrinsic integer types. That is, expressions 400 involving these types will be evaluated into result types which 401 reflect the standard rules for evaluation of C++ expressions. Should 402 it occur that such evaluation cannot return a correct result, an 403 exception will be thrown.The following program will throw an exception 404 and emit a error message at runtime if any of several events result in 405 an incorrect arithmetic type. Behavior of this program could vary 406 according to the machine architecture in question.</para> 407 408 <programlisting>#include <exception> 409#include <iostream> 410#include <safe> 411 412void f(){ 413 using namespace std; 414 safe<int> j; 415 try { 416 safe<int> i; 417 cin >> i; // could throw overflow ! 418 j = i * i; // could throw overflow 419 } 420 catch(std::exception & e){ 421 std::cout << e.what() << endl; 422 } 423 std::cout << j; 424}</programlisting> 425 </section> 426 </section> 427 </section> 428 429 <section> 430 <title>Acknowledgements</title> 431 432 <para>This proposal is a simplified version of Safe Numeics library 433 proposed for Boost. This effort was inspired by <ulink 434 url="http://safeint.codeplex.com">David LeBlanc's SafeInt Library</ulink> 435 .</para> 436 </section> 437 438 <section id="safe_numerics.bibliography"> 439 <title>References</title> 440 441 <biblioentry> 442 <author> 443 <surname>Omer Katz</surname> 444 </author> 445 446 <title> 447 <ulink url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?"> 448 <ulink 449 url="http://boost.2283326.n4.nabble.com/SafeInt-code-proposal-td2663669.html">SafeInt 450 code proposal</ulink> 451 </ulink> 452 </title> 453 454 <publishername> 455 <ulink 456 url="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-proposals">Boost 457 Developer's List</ulink> 458 </publishername> 459 460 <abbrev>Katz</abbrev> 461 462 <abstract> 463 <para>Posts of various authors regarding a proposed SafeInt library 464 for boost</para> 465 </abstract> 466 </biblioentry> 467 468 <biblioentry> 469 <author> 470 <surname>David LeBlanc</surname> 471 </author> 472 473 <title> 474 <ulink 475 url="https://msdn.microsoft.com/en-us/library/ms972705.aspx">Integer 476 Handling with the C++ SafeInt Class</ulink> 477 </title> 478 479 <publishername> 480 <ulink url="https://www.cert.org">Microsoft Developer Network</ulink> 481 </publishername> 482 483 <date>January 7, 2004</date> 484 485 <abbrev>LeBlanc</abbrev> 486 </biblioentry> 487 488 <biblioentry> 489 <author> 490 <surname>David LeBlanc</surname> 491 </author> 492 493 <title> 494 <ulink url="https://safeint.codeplex.com">SafeInt</ulink> 495 </title> 496 497 <publishername> 498 <ulink url="https://www.cert.org">CodePlex</ulink> 499 </publishername> 500 501 <date>Dec 3, 2014</date> 502 503 <abbrev>LeBlanc</abbrev> 504 </biblioentry> 505 506 <biblioentry> 507 <author> 508 <surname>Jacques-Louis Lions</surname> 509 </author> 510 511 <title> 512 <ulink 513 url="https://en.wikisource.org/wiki/Ariane_501_Inquiry_Board_report">Ariane 514 501 Inquiry Board report</ulink> 515 </title> 516 517 <publishername> 518 <ulink 519 url="https://en.wikisource.org/wiki/Main_Page">Wikisource</ulink> 520 </publishername> 521 522 <date>July 19, 1996</date> 523 524 <abbrev>Lions</abbrev> 525 </biblioentry> 526 527 <biblioentry> 528 <author> 529 <surname>Daniel Plakosh</surname> 530 </author> 531 532 <title> 533 <ulink 534 url="https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/312-BSI.html">Safe 535 Integer Operations</ulink> 536 </title> 537 538 <publishername> 539 <ulink url="https://buildsecurityin.us-cert.gov">U.S. Department of 540 Homeland Security</ulink> 541 </publishername> 542 543 <date>May 10, 2013</date> 544 545 <abbrev>Plakosh</abbrev> 546 </biblioentry> 547 548 <biblioentry id="Seacord"> 549 <author> 550 <surname>Robert C. Seacord</surname> 551 </author> 552 553 <title> 554 <ulink 555 url="http://www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?">Secure 556 Coding in C and C++</ulink> 557 </title> 558 559 <edition>2nd Edition</edition> 560 561 <publishername>Addison-Wesley Professional</publishername> 562 563 <date>April 12, 2013</date> 564 565 <isbn>978-0321822130</isbn> 566 567 <abbrev>Seacord</abbrev> 568 </biblioentry> 569 570 <biblioentry> 571 <author> 572 <surname>Robert C. Seacord</surname> 573 </author> 574 575 <title> 576 <ulink 577 url="https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false">INT30-C. 578 Ensure that operations on unsigned integers do not wrap</ulink> 579 </title> 580 581 <publishername> 582 <ulink url="https://www.cert.org">Software Engineering Institute, 583 Carnegie Mellon University</ulink> 584 </publishername> 585 586 <date>August 17, 2014</date> 587 588 <abbrev>INT30-C</abbrev> 589 </biblioentry> 590 591 <biblioentry> 592 <author> 593 <surname id="INT32-C">Robert C. Seacord</surname> 594 </author> 595 596 <title> 597 <ulink 598 url="https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow">INT32-C. 599 Ensure that operations on signed integers do not result in 600 overflow</ulink> 601 </title> 602 603 <publishername> 604 <ulink url="https://www.cert.org">Software Engineering Institute, 605 Carnegie Mellon University</ulink> 606 </publishername> 607 608 <date>August 17, 2014</date> 609 610 <abbrev>INT32-C</abbrev> 611 </biblioentry> 612 </section> 613</article> 614