Correct Integer Operations With Minimal Runtime Penalties Robert Ramey Robert Ramey Software Development 22 December 2016
Library Internals This library should compile and run correctly on any conforming C++14 compiler. The Safe Numerics library is implemented in terms of some more fundamental software components described here. It is not necessary to know about these components to use the library. This information has been included to help those who want to understand how the library works so they can extend it, correct bugs in it, or understand it's limitations. These components are also interesting in their own right. For all these reasons, they are described here. In general terms, the library works in the following manner: All unary/binary expressions where one of the operands is a "safe" type are Overloaded. These overloads are declared and defined in the header file "safe_integer.hpp". SFINAE - "Substitution Failure Is Not An Error and std::enable_if are key features of C++ used to define these overloads in a correct manner. Each overloaded operation implements the following at compile time: Retrieve range of values for each operand of type T from std::numeric_limits<T>::min() and std::numeric_limits<T>::max(). Given the ranges of the operands, determine the range of the result of the operation using interval arithmetic. This is implemented in the "interval.hpp" header file using constexpr facility of C++14. if the range of the result type includes the range of the result of the operation, no run time checking of the result is necessary. So the operation reduces to the original built-in C/C++ operation. Otherwise, the operation is implemented as a "checked integer operation" at run time. This operation returns a variant which will contain either a correct result or an exception enum indicating why a correct result could not be obtained. The variant object is implemented in the header file "checked_result.hpp" and the checked operations are implemented in "checked.hpp". if a valid result has been obtained, it is passed to the caller. Otherwise, an exception is invoked.
Current Status The library is currently in the Boost Review Queue. The proposal submission can be found in the Boost Library Incubator The library is currently limited to integers. Although care was taking to make the library portable, it's likely that at least some parts of the implementation - particularly checked arithmetic - depend upon two's complement representation of integers. Hence the library is probably not currently portable to other architectures. Currently the library permits a safe<int> value to be uninitialized. This supports the goal of "drop-in" replacement of C++/C built-in types with safe counter parts. On the other hand, this breaks the "always valid" guarantee. The library is not quite a "drop-in" replacement for all built-in integer types. In particular, C/C++ implements implicit conversions and promotions between certain integer types which are not captured by the operation overloads used to implement the library. In practice these case are few and can be addressed with minor changes to the user program to avoid these silent implicit conversions.