Library Documentation Index

Safe Numerics

PrevUpHomeNext

Arithmetic Expressions Can Yield Incorrect Results

When some operation on signed integer types results in a result which exceeds the capacity of a data variable to hold it, the result is undefined. In the case of unsigned integer types a similar situation results in a value wrap as per modulo arithmetic. In either case the result is different than in integer number arithmetic in the mathematical sense. This is called "overflow". Since word size can differ between machines, code which produces mathematically correct results in one set of circumstances may fail when re-compiled on a machine with different hardware. When this occurs, most C++ programs will continue to execute with no indication that the results are wrong. It is the programmer's responsibility to ensure such undefined behavior is avoided.

This program demonstrates this problem. The solution is to replace instances of built in integer types with corresponding safe types.

//  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 <boost/safe_numerics/safe_integer.hpp>

int main(int, const char *[]){
    std::cout << "example 1:";
    std::cout << "undetected erroneous expression evaluation" << std::endl;
    std::cout << "Not using safe numerics" << std::endl;
    try{
        std::int8_t x = 127;
        std::int8_t y = 2;
        std::int8_t z;
        // this produces an invalid result !
        z = x + y;
        std::cout << "error NOT detected!" << std::endl;
        std::cout << (int)z << " != " << (int)x << " + " << (int)y << 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;
        safe<std::int8_t> x = INT_MAX;
        safe<std::int8_t> y = 2;
        safe<std::int8_t> z;
        // rather than producing an invalid result an exception is thrown
        z = x + y;
    }
    catch(const std::exception & e){
        // which we can catch here
        std::cout << "error detected:" << e.what() << std::endl;
    }
    return 0;
}
example 1:undetected erroneous expression evaluation
Not using safe numerics
error NOT detected!
-127 != 127 + 2
Using safe numerics
error detected:converted signed value too large: positive overflow error
Program ended with exit code: 0

PrevUpHomeNext