| ## Safe Numerics

### Mixing Data Types Can Create Subtle Errors

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:

    //  Copyright (c) 2018 Robert Ramey
    //
    // Distributed under the Boost Software License, Version 1.0. (See
    // accompanying file LICENSE_1_0.txt or copy at
    // http://www.boost.org/LICENSE_1_0.txt)

    #include <iostream>
    #include <cstdint>

    #include <boost/safe_numerics/safe_integer.hpp>

    using namespace std;
    using namespace boost::safe_numerics;

    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 4: ";
        cout << "mixing types produces surprising results" << endl;
        try {
            std::cout << "Not using safe numerics" << std::endl;
            // problem: mixing types produces surprising results.
            f(100, 100);  // works as expected
            f(100, -100); // wrong result - unnoticed
            cout << "error NOT detected!" << endl;;
        }
        catch(const std::exception & e){
            // never arrive here
            cout << "error detected:" << e.what() << 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
            cout << "error NOT detected!" << endl;;
        }
        catch(const std::exception & e){
            cout << "error detected:" << e.what() << endl;;
        }
        return 0;
    }

Here is the output of the above program:

    example 4: mixing types produces surprising results
    Not using safe numerics
    10000
    4294957296
    error NOT detected!
    Using safe numerics
    10000
    error detected!converted negative value to unsigned: domain error

This solution is simple, just replace instances of `int` with `safe<int>`.