Document number: | P0228R2
Project: | Programming Language C++
Audience: | SG-6
Author: | Robert Ramey
Contact: | ramey@rrsd.com
Date: | 2016-02-16

# A Proposal to Add Safe Integer Types to the Standard Library

## Motivation

Arithmetic operations in C++ are NOT guaranteed to yield a correct mathematical result. This feature is inherited from the early days of C. The behavior of `int`, `unsigned int` and others were designed to map closely to the underlying hardware. Computer hardware implements these types as a fixed number of bits. When the result of arithmetic operations exceeds this number of bits, the result will not be arithmetically correct. The following example illustrates this problem.

    int f(int x, int y){
        // this returns an invalid result for some legal values of x and y !
        return x + y;
    }

## Impact On the Standard

This proposal is a pure library extension. It does not require changes to any standard classes, functions or headers. It might benefit from relaxing some of the conditions on aggregate types. It has been implemented in and requires standard C++/14.

## Design Decisions

The template class is designed to function as closely as possible as a drop-in replacement for corresponding built-in integer types.

1. "Drop In Replacement for Any Integer Type"

   The template class is designed to function as closely as possible as a drop-in replacement for corresponding built-in integer types. Ideally, one should be able to just substitute safe<T> for all instances of T in any program and expect it compile and execute as before with no other changes.

   Since C++ permits freely mixing signed and unsigned integer types in expressions, safe versions of these types can also be. This complicates the implementation of the library to significant degree.

2. "Return No Incorrect Results"

   Usage of a safe type in a binary expression is guaranteed to either return an arithmetically correct result or throw a standard exception.

3. "Automatically Inter operate with built-in integer types"

   The usage of a safe type in binary expression "infects" the expression by returning another safe type. This is designed to avoid accidentally losing the safety of the expression.

4. "Uses <limits> instead of type traits"

   Implementation of a library such as this necessarily keeps track of the types of data objects. The most common way to do this is using type_traits such as `std::is_integral`, `std::is_unsigned`, `std::is_arithmetic`, etc. This doesn't work very well for a few reasons:

   - These are defined by the standard to apply only to built-in types. Specializing these traits for new types such as safe<int> would conflict with the standard.

   - We are allowed to create specialization of std::numeric_limits for our own types - including safe<T>. So this works well for us.

   - safe<T> might be implemented in such as way that it would work for unforeseen integer-like types such as "money". Numeric limits has more complete information about these types which might make it easier to extend the library.

5. "Performance"

   Performance will depend on the implementation and subject to the constraints above. This design will permit the usage of template meta-programming to eliminate runtime performance penalties in some cases. In the following example, there is no runtime penalty required to guarantee that incorrect results will never be generated.

       #include <cstdint>
       #include <safe>

       using namespace std;

       int f(safe<int8_t> i){
           // C++ promotion rules make overflow on multiplication impossible!
           // cannot fail on return
           // zero performance penalty
           return i * i;
       }

       int8_t f(safe<int8_t> i){
           // C++ promotion rules make overflow on multiplication impossible!
           // but result could be truncated on return
           // so result must be checked at runtime incurring a runtime penalty
           return i * i;      // cannot overflow on multiplication,
       }

   Some processors have the ability to detect erroneous results but the C++ language doesn't include the ability to exploit these features. Implementor's of this library will have the option to exploit these features to diminish or eliminate runtime costs.

   If all else fails and the runtime cost is deemed too large for the program to bear, users will have the option of creating their own aliases for the types the program uses and assign them according to the whether they are building a "Debug" or "Release" version. This is not ideal, but would still be preferable to the current approach which generally consists of ignoring the possibility that C++ numeric operations may produce arithmetically incorrect results.

6. "No Extra Parameters"

   An alternative to this proposal would be a policy based design which would permit users to select or define actions to be taken in the case of errors. This is quite possible and likely useful. However, the simplicity usage of the current proposal is an important feature. So I decided not to include it.

7. "No other safe types"

   Other ideas come to mind such as `safe<Min, Max>`, `safe_literal<Value>`, and others. I excluded these in the spirit of following the controlling purpose of making a "drop in replacement". Once one included these types into a program, they change the semantics of the program so that it's not really C++ any more. There is a place for these ideas, (see below), but I don't think the standard library is that place.

## Existing Implementations

This proposal is a simpler version / subset of the Safe Numerics library in development by Robert Ramey on the Boost Library Incubator. It is compatible with this proposal but it also includes:

- Policy classes for error handling

- Policy classes for type promotion. These permit substitution of C++ standard type promotion rules with other ones which can reduce or eliminate the need for runtime error checking code.

- Other safe types such as safe_integer_range<Min, Max>.

- Complete documentation including internal operation

Without comment, here are implementations of libraries which are in some way similar to this proposal:

- Robert Leahy, Safe integer utilities for C++11

- David LeBlanc, SafeInt

- David Stone, Bounded Integer

## Technical Specifications

### Type Requirements

## Types

### safe<T>

#### Description

A `safe<T>` can be used anywhere a type T can be used. Any expression which uses this type is guaranteed to return an arithmetically correct value or trap in some way.

#### Notation

Symbol | Description
--- | ---
`T` | Underlying type from which a safe type is being derived

#### Template Parameters

Parameter | Type Requirements | Description
--- | --- | ---
`T` | Integer | The underlying type. Currently only integer types supported

See examples below.

#### Model of

Integer

SafeNumeric

#### Valid Expressions

Implements all expressions defined by the SafeNumeric type requirements.

`safe<T>` is meant to be a "drop-in" replacement of the intrinsic integer types.

The type of an expression of type safe<T> op safe<U> will be safe<R> where R would be the same as the type of the expression T op U.That is, expressions involving these types will be evaluated into result types which reflect the standard rules for evaluation of C++ expressions. Should it occur that such evaluation cannot return a correct result, an std::exception will be thrown.

#### Header

`#include <safe>`

#### Example of use

`safe<T>` is meant to be a "drop-in" replacement of the intrinsic integer types. That is, expressions involving these types will be evaluated into result types which reflect the standard rules for evaluation of C++ expressions. Should it occur that such evaluation cannot return a correct result, an exception will be thrown.The following program will throw an exception and emit a error message at runtime if any of several events result in an incorrect arithmetic type. Behavior of this program could vary according to the machine architecture in question.

    #include <exception>
    #include <iostream>
    #include <safe>

    void f(){
        using namespace std;
        safe<int> j;
        try {
            safe<int> i;
            cin >> i;       // could throw overflow !
            j = i * i;      // could throw overflow
        }
        catch(std::exception & e){
           std::cout << e.what() << endl;
        }
        std::cout << j;
    }

## Acknowledgements

This proposal is a simplified version of Safe Numeics library proposed for Boost. This effort was inspired by David LeBlanc's SafeInt Library .

## References

Omer Katz

SafeInt code proposal

Boost Developer's List Katz

Posts of various authors regarding a proposed SafeInt library for boost

David LeBlanc

Integer Handling with the C++ SafeInt Class

Microsoft Developer Network
January 7, 2004
LeBlanc
David LeBlanc

SafeInt

CodePlex
Dec 3, 2014
LeBlanc
Jacques-Louis Lions

Ariane 501 Inquiry Board report

Wikisource
July 19, 1996
Lions
Daniel Plakosh

Safe Integer Operations

U.S. Department of Homeland Security
May 10, 2013
Plakosh
Robert C. Seacord

Secure Coding in C and C++

2nd Edition Addison-Wesley Professional
April 12, 2013
978-0321822130 Seacord
Robert C. Seacord

INT30-C. Ensure that operations on unsigned integers do not wrap

Software Engineering Institute, Carnegie Mellon University
August 17, 2014
INT30-C
Robert C. Seacord

INT32-C. Ensure that operations on signed integers do not result in overflow

Software Engineering Institute, Carnegie Mellon University
August 17, 2014
INT32-C