![]() |
Safe Numerics |
C++ contains signed and unsigned integer types. In spite of their names, they function differently which often produces surprising results for some operands. Program errors from this behavior can be exceedingly difficult to find. This has lead to recommendations of various ad hoc "rules" to avoid these problems. It's not always easy to apply these "rules" to existing code without creating even more bugs. Here is a typical example of this problem:
#include <iostream>
#include <cstdint>
#include "../include/safe_integer.hpp"
#include "../include/cpp.hpp"
using namespace std;
using namespace boost::numeric;
void f(const unsigned int & x, const int8_t & y){
cout << x * y << endl;
}
void safe_f(
const safe<unsigned int> & x,
const safe<int8_t> & y
){
cout << x * y << endl;
}
int main(){
cout << "example 10: ";
cout << "mixing types produces surprising results" << endl;
try {
std::cout << "Not using safe numerics" << std::endl;
// problem: arithmetic operations can yield incorrect results.
f(100, 100); // works as expected
f(100, -100); // wrong result - unnoticed
}
catch(std::exception){
// never arrive here
std::cout << "error detected!" << std::endl;
}
try {
// solution: use safe types
std::cout << "Using safe numerics" << std::endl;
safe_f(100, 100); // works as expected
safe_f(100, -100); // throw error
}
catch(const exception & e){
cout << "detected error:" << e.what() << endl;;
}
return 0;
}
Here is the output of the above program:
example 10: mixing types produces surprising results Not using safe numerics 10000 4294957296 Using safe numerics 10000 detected error:converted negative value to unsigned
This solution is simple, Just replace instances of the
intwith safe<int>.