...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Safe Numerics |
This type contains the functions to return a safe type corresponding to the C++ type resulting from a given arithmetic operation.
Usage of this policy with safe types will produce the exact same arithmetic results that using normal unsafe integer types will. Hence this policy is suitable as a drop-in replacement for these unsafe types. Its main function is to trap incorrect arithmetic results when using C++ for integer arithmetic.
As an example of how this works consider C++ rules from section 5 of the standard - "usual arithmetic conversions".
void int f(int x, int y){ auto z = x + y; // z will be of type "int" return z; }
According to these rules, z will be of type int. Depending on the values of x and y, z may or may not contain the correct arithmetic result of the operation x + y.
using safe_int = safe<int, native>; void int f(safe_int x, safe_int y){ auto z = x + y; // z will be of type "safe_int" return z; }
The following example illustrates the native
type being
passed as a template parameter for the type safe<int>
.
This example is slightly contrived in that safe<int>
has native
as its default promotion parameter so explicitly
using native
is not necessary.
#include <cassert> #include <boost/numeric/safe_numerics/safe_integer.hpp> #include <boost/numeric/safe_numerics/native.hpp> int main(){ using namespace boost::numeric; // use native promotion policy where C++ standard arithmetic // might lead to incorrect results using safe_int8 = safe<std::int8_t, native>; try{ safe_int8 x = 127; safe_int8 y = 2; safe_int8 z; // rather than producing an invalid result an exception is thrown z = x + y; assert(false); // never arrive here } catch(std::exception & e){ // which we can catch here std::cout << e.what() << std::endl; } // When result is an int, C++ promotion rules guarentee // that there will be no incorrect result. // In such cases, there is no runtime overhead from using safe types. safe_int8 x = 127; safe_int8 y = 2; safe<int, native> z; // z can now hold the result of the addition of any two 8 bit numbers z = x + y; // is guaranteed correct without any runtime overhead or exception. return 0; }