From 0d3af22a53ee5ecd06cd2f070f912fc214b2780f Mon Sep 17 00:00:00 2001
From: Robert Ramey
Date: Fri, 30 Jan 2015 15:55:19 -0800
Subject: [PATCH] corrections adjustments motivated by first real review of the
library
---
CMake/CMakeLists.txt | 114 +++-----
CMake/CTestConfig.cmake | 2 -
doc/boostbook/numeric_concept.xml | 19 +-
doc/boostbook/overflow.xml | 7 +-
doc/boostbook/safe.xml | 33 ++-
doc/boostbook/safe_cast.xml | 12 +-
doc/boostbook/safe_compare.xml | 6 +-
doc/boostbook/safe_introduction.xml | 102 +++++--
doc/boostbook/safe_numerics.xml | 397 ++++++++++++++++++++++----
doc/boostbook/safe_signed_range.xml | 47 ++-
doc/boostbook/safe_unsigned_range.xml | 120 +++++++-
doc/boostbook/tutorial.xml | 73 +++--
doc/html/acknowledgements.html | 15 +-
doc/html/change_log.html | 3 +-
doc/html/concepts.html | 26 +-
doc/html/functions.html | 37 +--
doc/html/index.html | 24 +-
doc/html/introduction.html | 87 ++++--
doc/html/notes.html | 5 +-
doc/html/rationale.html | 51 +++-
doc/html/references.html | 106 ++++++-
doc/html/tutorial.html | 281 ++++++++++++++----
doc/html/types.html | 45 +--
examples/example1.cpp | 21 +-
examples/example2.cpp | 6 +-
examples/example3.cpp | 28 +-
examples/example4.cpp | 28 +-
include/safe_integer.hpp | 11 +-
include/safe_range.hpp | 2 +-
test/test.cpp | 162 -----------
test/test_divide1.cpp | 37 ---
test/test_modulus1.cpp | 37 ---
test/test_multiply1.cpp | 37 ---
test/test_subtract1.cpp | 37 ---
34 files changed, 1261 insertions(+), 757 deletions(-)
delete mode 100644 test/test.cpp
delete mode 100644 test/test_divide1.cpp
delete mode 100644 test/test_modulus1.cpp
delete mode 100644 test/test_multiply1.cpp
delete mode 100644 test/test_subtract1.cpp
diff --git a/CMake/CMakeLists.txt b/CMake/CMakeLists.txt
index 5075363..d2afe82 100644
--- a/CMake/CMakeLists.txt
+++ b/CMake/CMakeLists.txt
@@ -116,18 +116,15 @@ link_directories("${Boost_LIBRARY_DIRS}")
###########################
###########################
-# testing and submitting test results
+# testing and submitting test results to the test dashboard
include (CTest)
if(0)
-## This file should be placed in the root directory of your project.
-## Then modify the CMakeLists.txt file in the root directory of your
-## project to incorporate the testing dashboard.
-## # The following are required to uses Dart and the Cdash dashboard
-## ENABLE_TESTING()
-## INCLUDE(CTest)
+## Create a file named CTestConfig.cmake adjacent to the current file.
+## This new file should contain the following:
+
set(CTEST_PROJECT_NAME "Safe Numerics")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
@@ -139,79 +136,52 @@ set(CTEST_DROP_SITE_CDASH TRUE)
endif()
+function( [arg1 [arg2 [arg3 ...]]])
+ COMMAND1(ARGS ...)
+ COMMAND2(ARGS ...)
+ ...
+endfunction()
+
+###########################
+# test targets
+
# the "include (CTest)" above includes enable_testing()
# so the following line isn't necessary
# enable_testing()
-message(STATUS "test_cast")
-add_executable( test_cast ../test/test_cast.cpp )
-target_link_libraries( test_cast ${Boost_LIBRARIES} )
-add_test(NAME test_cast COMMAND test_cast)
-
-message(STATUS "test_add")
-add_executable( test_add ../test/test_add.cpp )
-target_link_libraries( test_add ${Boost_LIBRARIES} )
-add_test(NAME test_add COMMAND test_add)
-
-message(STATUS "test_subtract")
-add_executable( test_subtract ../test/test_subtract.cpp )
-target_link_libraries( test_subtract ${Boost_LIBRARIES} )
-add_test(NAME test_subtract COMMAND test_subtract)
-
-message(STATUS "test_multiply")
-add_executable( test_multiply ../test/test_multiply.cpp )
-target_link_libraries( test_multiply ${Boost_LIBRARIES} )
-add_test(NAME test_multiply COMMAND test_multiply)
-
-message(STATUS "test_divide")
-add_executable( test_divide ../test/test_divide.cpp )
-target_link_libraries( test_divide ${Boost_LIBRARIES} )
-add_test(NAME test_divide COMMAND test_divide)
-
-message(STATUS "test_modulus")
-add_executable( test_modulus ../test/test_modulus.cpp )
-target_link_libraries( test_modulus ${Boost_LIBRARIES} )
-add_test(NAME test_modulus COMMAND test_modulus)
-
-message(STATUS "test_compare")
-add_executable( test_compare ../test/test_compare.cpp)
-target_link_libraries( test_compare ${Boost_LIBRARIES} )
-add_test(NAME test_compare COMMAND test_compare)
-
-message(STATUS "test_conversion")
-add_executable( test_conversion ../test/test_conversion.cpp)
-target_link_libraries( test_conversion ${Boost_LIBRARIES} )
-add_test(NAME test_conversion COMMAND test_conversion)
-
-message(STATUS "test0")
-add_executable( test0 ../test/test.cpp)
-target_link_libraries( test0 ${Boost_LIBRARIES} )
-add_test(NAME test0 COMMAND test)
-
-# examples
-message(STATUS "example1")
-add_executable( example1 ../examples/example1.cpp)
-target_link_libraries( example1 ${Boost_LIBRARIES} )
-add_test(NAME example1 COMMAND example1)
-
-message(STATUS "example2")
-add_executable( example2 ../examples/example2.cpp)
-target_link_libraries( example2 ${Boost_LIBRARIES} )
-add_test(NAME example2 COMMAND example2)
-
-message(STATUS "example3")
-add_executable( example3 ../examples/example3.cpp)
-target_link_libraries( example3 ${Boost_LIBRARIES} )
-add_test(NAME example3 COMMAND example3)
-
-message(STATUS "example4")
-add_executable( example4 ../examples/example4.cpp)
-target_link_libraries( example4 ${Boost_LIBRARIES} )
-add_test(NAME example4 COMMAND example4)
+file(GLOB test_list
+ RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../test/*.cpp"
+)
+foreach(file_path ${test_list})
+ string(REPLACE "../test/" "" file_name ${file_path})
+ string(REPLACE ".cpp" "" base_name ${file_name})
+ message(STATUS ${base_name})
+ add_executable(${base_name} ${file_path})
+ target_link_libraries(${base_name} ${Boost_LIBRARIES} )
+endforeach(file_path)
# end test targets
####################
+###########################
+# examples
+
+file(GLOB example_list
+ RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../examples/*.cpp"
+)
+foreach(file_path ${example_list})
+ string(REPLACE "../examples/" "" file_name ${file_path})
+ string(REPLACE ".cpp" "" base_name ${file_name})
+ message(STATUS ${base_name})
+ add_executable(${base_name} ${file_path})
+ target_link_libraries(${base_name} ${Boost_LIBRARIES} )
+endforeach(file_path)
+
+# end examples targets
+####################
+
####################
# add include headers to IDE
diff --git a/CMake/CTestConfig.cmake b/CMake/CTestConfig.cmake
index da7fa7a..a0b5924 100644
--- a/CMake/CTestConfig.cmake
+++ b/CMake/CTestConfig.cmake
@@ -2,8 +2,6 @@
## Then modify the CMakeLists.txt file in the root directory of your
## project to incorporate the testing dashboard.
## # The following are required to uses Dart and the Cdash dashboard
-## ENABLE_TESTING()
-## INCLUDE(CTest)
set(CTEST_PROJECT_NAME "Safe Numerics")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
diff --git a/doc/boostbook/numeric_concept.xml b/doc/boostbook/numeric_concept.xml
index 6644b93..bb8abce 100644
--- a/doc/boostbook/numeric_concept.xml
+++ b/doc/boostbook/numeric_concept.xml
@@ -15,9 +15,9 @@
library includes such specializations for all the primitive numeric types.
Note that this concept is distinct from the C++ standard library type
traits is_integral and is_arithmetic. These
- latter fullfill the requirement of the concept Numeric. But there are
- types T which fullfill this concept for which
- is_arithmetic<T>::value == false. For example see
+ latter fulfill the requirement of the concept Numeric. But there are types
+ T which fulfill this concept for which is_arithmetic<T>::value
+ == false. For example see
safe_signed_integer<int>.
@@ -65,7 +65,7 @@
std::numeric_limits<T>The numeric_limits class template provides a C++ program
- with information about various properties of the implementation’s
+ with information about various properties of the implementation's
representation of the arithmetic types. See C++ standard
18.3.2.2.
@@ -180,7 +180,7 @@
T
- predecrement
+ pre decrement
@@ -188,7 +188,7 @@
T
- preincrement
+ pre increment
@@ -276,7 +276,7 @@
T
- shift t right by ubits
+ shift t right by u bits
@@ -308,7 +308,8 @@
bool
- true if t greathan or equal to u, false otherwise
+ true if t greater than or equal to u, false
+ otherwise
@@ -456,5 +457,7 @@
int, safe_signed_integer<int>,
safe_signed_range<int>, etc.
+
+ The definition of this concept
diff --git a/doc/boostbook/overflow.xml b/doc/boostbook/overflow.xml
index 7b5cb51..d702f6d 100644
--- a/doc/boostbook/overflow.xml
+++ b/doc/boostbook/overflow.xml
@@ -16,13 +16,12 @@
Description
- If evironment supports C++ exceptions, this function throws the
+ If environment supports C++ exceptions, this function throws the
exception .If the environment does not support C++ exceptions, the user should
- implement this function and expect it to be called when appropriate.
- Otherwise, function is implemented by the library so that it throws the
- standard library exception std::out_of_range(msg).
+ implement this function and expect it to be called when
+ appropriate.boost/config.hpp defines BOOST_NO_EXCEPTIONS
when the environment doesn't support exceptions. It is by checking for the
diff --git a/doc/boostbook/safe.xml b/doc/boostbook/safe.xml
index 01086ec..8dcb3dc 100644
--- a/doc/boostbook/safe.xml
+++ b/doc/boostbook/safe.xml
@@ -47,6 +47,12 @@
object of type safe<T>
+
+
+ su
+
+ object of type safe<U>
+
@@ -92,10 +98,6 @@
Model ofNumeric
-
- If the resulting type of the operation t op u is V, the resulting
- type of the operations st op su, t op su and st op u will be
- safe<V>;
@@ -113,7 +115,7 @@
Expression
- Result
+ Result TypeDescription
@@ -123,8 +125,8 @@
st op u
- safe<decltype(t
- op u)>
+ typeof(t op
+ u)op is any valid binary operator for type
T
@@ -133,8 +135,8 @@
t op su
- safe<decltype(t
- op u)>
+ typeof(t op
+ u)op is any valid binary operator for type
T
@@ -143,20 +145,21 @@
st op su
- safe<decltype(t
- op u)>
+ typeof(t op
+ u)op is any valid binary operator for type
T
- T * U
+ st(t)
- typeof(T *
- U)
+ safe<T>
- The underlying integer type
+ construct a instance of safe<T> from
+ t
diff --git a/doc/boostbook/safe_cast.xml b/doc/boostbook/safe_cast.xml
index 99d3d5f..c094cb2 100644
--- a/doc/boostbook/safe_cast.xml
+++ b/doc/boostbook/safe_cast.xml
@@ -16,7 +16,9 @@ T safe_cast(const U & u);
Converts one Numeric
type to another. Throws an std::out_of_range exception if
- such a conversion is not possible without changing the value.
+ such a conversion is not possible without changing the value. This
+ function is part of the implementation of the safe numerics library. It's
+ been made publicly because it might be useful in related contexts.
@@ -58,17 +60,11 @@ T safe_cast(const U & u);
Preconditions
- The value of u must be representabl by the type T. If
+ The value of u must be representable by the type T. If
this is not true, an std::out_of_range exception will be
thrown.
-
- Complexity
-
- Constant - O(0).
-
-
Header
diff --git a/doc/boostbook/safe_compare.xml b/doc/boostbook/safe_compare.xml
index 770b62a..e0fc432 100644
--- a/doc/boostbook/safe_compare.xml
+++ b/doc/boostbook/safe_compare.xml
@@ -35,8 +35,10 @@ bool safe_compare::not_equal(const T & lhs, const U & rhs);
+ check that an error is made in the conversion. This function guarantees a
+ correct result regardless of the types of the arguments. It's used in the
+ implementation of the safe numerics library. It has been made publicly
+ accessible in because it might be useful in other contexts.
diff --git a/doc/boostbook/safe_introduction.xml b/doc/boostbook/safe_introduction.xml
index fd9190e..c18a751 100644
--- a/doc/boostbook/safe_introduction.xml
+++ b/doc/boostbook/safe_introduction.xml
@@ -7,18 +7,49 @@
Problem
- Arithmetic operations in C++ are NOT guarenteed to yield a correct
+ Arithmetic operations in C++ are NOT guaranteed to yield a correct
mathematical result. This feature is inherited from the early days of C.
The behavior of int, unsigned int and others
were designed to map closely to the underlying hardware. Computer hardware
implements these types as a fixed number of bits. When the result of
- arithmetic operations exceeds this number of bits, the result is undefined
- and usually not what the programmer intended. It is incumbent up the C/C++
- programmer to guarentee that this behavior does not result in incorrect
- behavior of the program. There are no language facilities which do this.
- They have to be explicitly addressed in the program code. This is
- exceeding tedious and laborious for a programmer to do. Besides, adding
- this code would introduce another source of errors.
+ arithmetic operations exceeds this number of bits, the result will not be
+ arithmetically correct. The following example illustrates this
+ problem.
+
+ int f(int x, int y){
+ // this returns an invalid result for some legal values of x and y !
+ return x + y;
+}
+
+
+ It is incumbent up the C/C++ programmer to guarantee that this
+ behavior does not result in incorrect or unexpected operation of the
+ program. There are no language facilities which do this. They have to be
+ explicitly addressed in the program code. There are a number of ways to do
+ this. SeeINT32-C seems to recommend the following
+ approach.
+
+ int f(int x, int y){
+ if (((y > 0) && (x > (INT_MAX - y)))
+ || ((y < 0) && (x < (INT_MIN - x)))) {
+ /* Handle error */
+ }
+ return x + y;
+}
+
+
+ This will indeed trap the error. However, it would be tedious and
+ laborious for a programmer to do alter his code to do. Altering code in
+ this way for all arithmetic operations would likely render the code
+ unreadable and add another source of potential programming errors. This
+ approach is clearly not functional when the expression is even a little
+ more complex as is shown in the following example.
+
+ int f(int x, int y, int z){
+ // this returns an invalid result for some legal values of x and y !
+ return x + y * z;
+}
+
@@ -26,11 +57,22 @@
This library implements special versions of int, unsigned, etc.
which behave exactly like the original ones EXCEPT that the results of
- these operations are checked to be sure any possible errors resulting from
- undefined arithmetic behavior are trapped at compile time (if possible) or
- at runtime. This will permit one to write arithmetic expressions without
- resulting in an erroneous result. Instead, one and only one of the
- following is guarenteed to occur.
+ these operations are guaranteed to be either arithmetically correct or
+ invoke an error. Using this library, the above would be rendered
+ as:
+
+ #include <boost/safe_numeric/safe_integer.hpp>
+
+int f(safe<int> x, safe<int> y){
+ return x + y; // throw exception if correct result cannot be returned
+}
+
+
+ The addition expression is checked at runtime or (if possible)
+ compile time to trap any possible errors resulting from incorrect
+ arithmetic behavior. This will permit one to write arithmetic expressions
+ that cannot produce an erroneous result. Instead, one and only one of the
+ following is guaranteed to occur.
@@ -50,14 +92,37 @@
safe_signed_range<MIN, MAX> and
safe_unsigned_range<MIN, MAX> which will throw an
exception if an attempt is made to store a result which is outside the
- closed range [MIN, MAX]. By using these types, on can guarentee correct
- runtime behavior without the need for exception handling.
+ closed range [MIN, MAX].
+
+
+
+ Summary
+
+ Using techniques of C++ including overloading, template
+ metaprogramming, and others, this library implements special versions of
+ int, unsigned, etc. named safe<int>,
+ safe<unsigned int> etc. These behave exactly like the
+ original ones EXCEPT that expressions involving these types are checked to
+ guarantee any possible arithmetic errors are trapped at compile time (if
+ possible) or at runtime. Since these types are meant to be "drop-in"
+ replacements - they function in all other ways the same as the built-in
+ types they are meant to replace. So things which are legal - such as
+ assigning an signed to unsigned value are not trapped at compile time - as
+ they are legal C/C++ code - but rather checked at runtime to trap the case
+ where this (legal) operation would lead to an arithmetically incorrect
+ result.
+
+ Note that the library addresses arithmetical errors generated by
+ straightforward C/C++ expressions. Some of these arithmetic errors are
+ defined as conforming to C/C++ standard while others are not. So it's
+ misleading to characterize this library as addressing undefined behavior
+ of C/C++ numeric expressions.Requirements
- This library is is composed entirely of C++ Headers. I requires a
+ This library is composed entirely of C++ Headers. I requires a
compiler compatible with the C++11 standard.The following Boost Libraries must be installed in order to use this
@@ -101,7 +166,8 @@
Analogous issues arise for floating point types but they are not currently
addressed by this version of the library. User or Library defined types
such as arbitrary precision integers can also have this problem. Extension
- of this library to these other types is not currently under
- development
+ of this library to these other types is not currently under development
+ but may be addressed in the future. This is one reason why the library
+ name is "safe numeric" rather than "safe integer" library.
diff --git a/doc/boostbook/safe_numerics.xml b/doc/boostbook/safe_numerics.xml
index 4cefda2..4a0afef 100644
--- a/doc/boostbook/safe_numerics.xml
+++ b/doc/boostbook/safe_numerics.xml
@@ -5,7 +5,7 @@
name="Safe Numerics">
Safe Numerics
-
+ Robert
@@ -19,12 +19,14 @@
- http://www.boost.org/LICENSE_1_0.txt">Subject to Boost Software License
+ http://www.boost.org/LICENSE_1_0.txt">Subject
+ to Boost Software LicenseSafe integer operations
- Numerics
+ NumericsIt was a lot of code in one header - 6400 lines. Very unwieldy
- to understand and modify.
+ to understand, modify and maintain.
@@ -68,15 +70,7 @@
- The package I downloaded didn't have a test suite
-
-
-
- I believe the original SafeInt
- library is not easily found. MSVC 10 has this built in so I seems that
- they've decided to make it less attractive to use on other
- systems.
+ I could find not test suite for the library.
@@ -91,7 +85,7 @@
- Concepts
+ Type Requirements
@@ -100,14 +94,14 @@
Types
+
+
-
-
@@ -123,6 +117,13 @@
xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+ Exception Safety
+
+ All operations in this library are exception safe and meet the
+ strong guarantee.
+
+
Rationale
@@ -135,7 +136,7 @@
- There are a number of
+ There are a number of reasons:
@@ -155,24 +156,129 @@
Why is there no policy driven design for handling
- overflows
-
- The question was - to which type does one apply it to?
- Consider the following example:
-
- safe<int, overflow_policy_1> t1 = 2;
-safe<int, overflow_policy_2> t2 = 4;
-unsigned int x = t1 - t2; // which policy should be invoked?
+ overflows?
+
+
+ This is planned for a future version of the library. However,
+ attempts to implement this idea have so far failed as it turns out
+ to more technically challenging than one would think. Rather than
+ wait for a future event that might never happen, it was decided to
+ release the library without this feature.
+ Why is Boost.Convert not used.
+
+ I couldn't figure out how to use it from the
documentation.
+
+
+
+
+
+ Why is the library named "safe ..." rather than something like
+ "checked ..." ?
+
+
+ I used "safe" in large part this is what has been used by
+ other similar libraries. Maybe a better word might have been
+ "correct" but that would raise similar concerns. I'm not inclined to
+ change this. I've tried to make it clear in the documentation what
+ the problem that the library addressed is
+
+
+
+
+
+ Given that the library is called "numerics" why is floating
+ point arithmetic not addressed?
+
+
+
+ Actually, I believe that this can/should be applied to any
+ type T which satisfies the type requirement "Numeric" type as
+ defined in the documentation. So there should be specializations
+ safe<float> et. al. and eventually safe<fixed_decimal>
+ etc. But the current version of the library only addresses integer
+ types. Hopefully the library will evolve to match the promise
+ implied by it's name.
+
+
+
+
+
+ Isn't putting a defensive check just before any potential UB,
+ is often considered a bad practice?
+
+
+
+ By whom? Is leaving code which can produce incorrect results
+ better? Note that the documentation contains references to various
+ sources which recommend exactly this approach to mitigate the
+ problems created by this C/C++ behavior.
+
+
+
+
+
+ Why are safe_compare and safe_cast included in the library?
+ The don't really fit with the "drop-in" replacement idea for
+ built-in types.
+
+
+
+ They are part of the implementation of the library. I thought
+ they would be useful outside the formal context of the library so I
+ make access to them public.
+
+
+
+
+
+ It looks like it presumes two's complement arithmetic at the
+ hardware level. So this library is not portable - correct? What
+ about other hardware architectures?
+
+
+
+ Correct. Almost all hardware in current use two's complement
+ arithmetic. This library works all and only on all such machines.
+ For example, if one were to implement 48 bit integers with two's
+ complement arithmetic, the save .. versions could be used without
+ change. To support hardware which does not use two's complement
+ arithmetic, at least part of the library would have to be
+ re-implemented.
+
+
+
+
+
+ Why do you specialize numeric_limits for "safe" types? Do you
+ need it?
+
+
+
+ safe<T> behaves like a "number" just as int does. It has
+ max, min, etc Any code which uses numeric limits to test a type T
+ should works with safe<T>. safe<T> is a drop-in
+ replacement for T so it has to implement all the operations.
+
+
+
+
+
+
+
+
+
+
+
@@ -183,49 +289,220 @@ unsigned int x = t1 - t2; // which policy should be invoked?
This is the initial version.
-
- Acknowledgements
+
+ Bibliography
- David
- LeBlanc's is the author of SafeInt3
- library which motivated this work
-
+
+
+ Robert C. Seacord
+
-
- References
+
+ Secure
+ Coding in C and C++
+
-
-
- David LeBlanc, Codeplex
- SafeInt Page
-
+ 2nd Edition
-
- Daniel Plakosh, Safe
- Integer Operations
-
+ Addison-Wesley Professional
-
- Omer Katz, SafeInt
- code proposal, Boost.SafeInt
-
+ April 12, 2013
-
- Software Engineering Institute, Carnegie Mellon, 978-0321822130
+
+ Seacord
+
+
+
+
+ Robert C. Seacord
+
+
+
+ INT32-C.
Ensure that operations on signed integers do not result in
- overflow
-
+ overflow
+
-
- Will Dietz, Peng Li,y John Regehr,y and Vikram Adve,
+ Software Engineering Institute,
+ Carnegie Mellon University
+
+
+ August 17, 2014
+
+ INT32-C
+
+
+
+
+ Daniel Plakosh
+
+
+
+ Safe
+ Integer Operations
+
+
+
+ U.S. Department of
+ Homeland Security
+
+
+ May 10, 2013
+
+ Plakosh
+
+
+
+
+ Will Dietz
+
+
+
+ Peng Li
+
+
+
+ John Regehr
+
+
+
+ Vikram Adve
+
+
+
+ Understanding
- Integer Overflow in C/C++
-
-
+ Integer Overflow in C/C++
+
+
+
+ Proceedings
+ of the 34th International Conference on Software Engineering (ICSE),
+ Zurich, Switzerland
+
+
+ June 2012
+
+
+
+
+ Lawerence Crowl
+
+
+
+
+ C++
+ Binary Fixed-Point Arithmetic
+
+
+
+
+ JTC1/SC22/WG21 -
+ The C++ Standards Committee - ISOCPP
+
+
+ January 15, 2012
+
+ Crowl
+
+
+
+
+ Forum Posts
+
+
+
+
+ C++
+ Binary Fixed-Point Arithmetic
+
+
+
+
+ ISO
+ C++ Standard Future Proposals
+
+
+ Forum
+
+
+ Posts of various authors regarding proposal to add safe integer
+ to C++ standard libraries
+
+
+
+
+
+ David LeBlanc
+
+
+
+ Integer
+ Handling with the C++ SafeInt Class
+
+
+
+ Microsoft Developer Network
+
+
+ January 7, 2004
+
+ LeBlanc
+
+
+
+
+ David LeBlanc
+
+
+
+ SafeInt
+
+
+
+ CodePlex
+
+
+ Dec 3, 2014
+
+ LeBlanc
+
+
+
+
+ Omer Katz
+
+
+
+
+ SafeInt
+ code proposal
+
+
+
+
+ Boost
+ Developer's List
+
+
+ Katz
+
+
+ Posts of various authors regarding a proposed SafeInt library
+ for boost
+
+
diff --git a/doc/boostbook/safe_signed_range.xml b/doc/boostbook/safe_signed_range.xml
index 58d5393..25fd5b9 100644
--- a/doc/boostbook/safe_signed_range.xml
+++ b/doc/boostbook/safe_signed_range.xml
@@ -2,8 +2,8 @@
- safe_signed_range<boost::intmax_t MIN,
- boost::intmax_tMAX>
+ safe_signed_range<boost::intmax_t MIN, boost::intmax_t
+ MAX>Description
@@ -13,6 +13,47 @@
in assigning an integer value outside of this range.
+
+ Notation
+
+
+
+
+
+
+
+
+
+ Symbol
+
+ Description
+
+
+
+
+
+ T, U, V
+
+ Types which model the Numeric concept
+
+
+
+ t, u, v
+
+ objects of types T
+
+
+
+ ssr
+
+ object of type safe_unsigned_range
+
+
+
+
+
+
Template Parameters
@@ -70,7 +111,7 @@
The usage of this type in an arithmetic expression will result in
another type fulfilling the Numeric concept.
+ linkend="safe_numerics.numeric">Numeric concept.
Operations on safe_signed_range will result in the same
diff --git a/doc/boostbook/safe_unsigned_range.xml b/doc/boostbook/safe_unsigned_range.xml
index 6221bb7..cd63525 100644
--- a/doc/boostbook/safe_unsigned_range.xml
+++ b/doc/boostbook/safe_unsigned_range.xml
@@ -2,14 +2,56 @@
- safe_unsigned_range<MIN, MAX>
+ safe_unsigned_range<boost::uintmax_t MIN, boost::uintmax_t
+ MAX>DescriptionThis type holds a integer in the range [MIN, MAX]. It will throw a
std::out_of_range exception for any operation which would
- result in assigning an integer value outside of this range.
+ result in assigning an integer value outside of this range.
+
+
+
+ Notation
+
+
+
+
+
+
+
+
+
+ Symbol
+
+ Description
+
+
+
+
+
+ T, U, V
+
+ Types which model the Numeric concept
+
+
+
+ t, u, v
+
+ objects of types T
+
+
+
+ sur
+
+ object of type safe_unsigned_range
+
+
+
+
@@ -37,7 +79,7 @@
MIN
- must be a positive integer literal
+ must be a non-negative integer literalThe minimum integer value that this type may hold
@@ -53,9 +95,7 @@
- MIN < MAX
-
-
+ MIN <= MAX
@@ -71,7 +111,73 @@
unsigned type will result in another unsigned type fulfilling the Numeric concept. This will be the
smallest unsigned integer type of sufficient size to hold the result of
- the operation.
+ the operation.
+
+
+
+ Valid Expressions
+
+
+
+
+
+
+
+
+
+
+
+ Expression
+
+ Result Type
+
+ Description
+
+
+
+
+
+ st op u
+
+ typeof(t op
+ u)
+
+ op is any valid binary operator for type
+ T
+
+
+
+ t op su
+
+ typeof(t op
+ u)
+
+ op is any valid binary operator for type
+ T
+
+
+
+ st op su
+
+ typeof(t op
+ u)
+
+ op is any valid binary operator for type
+ T
+
+
+
+ st(t)
+
+ safe<T>
+
+ construct a instance of safe<T> from
+ t
+
+
+
+
diff --git a/doc/boostbook/tutorial.xml b/doc/boostbook/tutorial.xml
index 05adacb..496524d 100644
--- a/doc/boostbook/tutorial.xml
+++ b/doc/boostbook/tutorial.xml
@@ -2,11 +2,10 @@
- Tutorial
+ Tutorial and Motivating Examples
- Problem: Arithmetic operations can yield in correct
- results.
+ Arithmetic operations can yield incorrect results.When some operation results in a result which exceeds the capacity
of a data variable to hold it, the result is undefined. This is called
@@ -14,7 +13,7 @@
produces correct results in one set of circumstances may fail when
re-compiled on a machine with different hardware. When this occurs, Most
C++ compilers will continue to execute with no indication that the results
- are wrong. It is the programmer's responsabiity to ensure such undefined
+ are wrong. It is the programmer's responsibility to ensure such undefined
behavior is avoided.This program demonstrates this problem. The solution is to replace
@@ -26,7 +25,17 @@
- Problem: Undetected overflow
+ Undetected overflow
+
+ A variation of the above is when a value is incremented/decremented
+ beyond it's domain. This is a common problem with for loops.
+
+
+
+
+
+ Undetected underflowA variation of the above is when a value is incremented/decremented
beyond it's domain. This is a common problem with for loops.
@@ -35,41 +44,63 @@
parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/>
-
- Problem: Implicit conversions change data values
+
+ Implicit conversions change data values
- A simple assign or arithment expression will generally convert all
- the terms to the same type. Sometimes this can silently change values. For
- example, when a signed data variable contains a negative type, assigning
- to a unsigned type will be permitted by any C/C++ compiler but will be
- treated as large unsigned value. Most modern compilers will emit a compile
- time warning when this conversion is performed. The user may then decide
- to change some data types or apply a static_cast. This is
- less than satisfactory for two reasons:
+ A simple assignment or arithmetic expression will generally convert
+ all the terms to the same type. Sometimes this can silently change values.
+ For example, when a signed data variable contains a negative type,
+ assigning to a unsigned type will be permitted by any C/C++ compiler but
+ will be treated as large unsigned value. Most modern compilers will emit a
+ compile time warning when this conversion is performed. The user may then
+ decide to change some data types or apply a static_cast. This
+ is less than satisfactory for two reasons:
- It may be unwield to change all the types to signed or
+ It may be unwieldy to change all the types to signed or
unsigned.
- Litering one's program with static_cast
+ Littering one's program with static_castmakes it more difficult to read.We may believe that our signed type will never contain a
negative value. If we use a static_cast to suppress the
- warning, we'll fail to detect a program error when it is commited.
+ warning, we'll fail to detect a program error when it is committed.
This is aways a risk with casts.This solution is the same as the above, Just replace instances of
- the int with safe<int>.
+ the int with safe<int>.
+
-
+
+ Array index value can exceed array limits
+
+ Using an intrinsic C++ array, it's very easy to exceed array limits.
+ This can fail to be detected when it occurs and create bugs which are hard
+ to find. There are several ways to address this, but one of the simplest
+ would be to use safe_unsigned_range;
+
+
+
+
+
+ Checking of initialization values can be easily overlooked
+
+ It's way too easy to overlook the checking of parameters received
+ from outside the current program.Without
+ safe integer, one will have to insert new code every time an integer
+ variable is retrieved. This is a tedious and error prone procedure.
diff --git a/doc/html/acknowledgements.html b/doc/html/acknowledgements.html
index 74f2fdd..db48cea 100644
--- a/doc/html/acknowledgements.html
+++ b/doc/html/acknowledgements.html
@@ -7,7 +7,7 @@
-
+