Safe Numerics |
If a divide by zero error occurs while a program is being compiled, there is not guarantee that it will be detected. This example shows a real example compiled with a recent version of CLang.
Source code includes a constant expression containing a simple arithmetic error.
The compiler emits a warning but otherwise calculates the wrong result.
Replacing int with safe<int> will guarantee that the error is detected at runtime
Operations using safe types are marked constexpr. So we can force the operations to occur at runtime by marking the results as constexpr. This will result in an error at compile time if the operations cannot be correctly calculated.
#include <stdexcept> #include <iostream> #include <boost/safe_numerics/safe_integer.hpp> int main(int, const char *[]){ // problem: cannot recover from arithmetic errors std::cout << "example 8: "; std::cout << "cannot detect compile time arithmetic errors" << std::endl; std::cout << "Not using safe numerics" << std::endl; try{ const int x = 1; const int y = 0; // will emit warning at compile time // will leave an invalid result at runtime. std::cout << x / y; // will display "0"! std::cout << "error NOT detected!" << std::endl; } catch(const std::exception &){ std::cout << "error detected!" << std::endl; } // solution: replace int with safe<int> std::cout << "Using safe numerics" << std::endl; try{ using namespace boost::safe_numerics; const safe<int> x = 1; const safe<int> y = 0; // constexpr const safe<int> z = x / y; // note constexpr here! std::cout << x / y; // error would be detected at runtime std::cout << " error NOT detected!" << std::endl; } catch(const std::exception & e){ std::cout << "error detected:" << e.what() << std::endl; } return 0; }
example 8: cannot detect compile time arithmetic errors Not using safe numerics 0error NOT detected! Using safe numerics error detected:positive overflow error Program ended with exit code: 0