A Proposal To Add Safe Integer Types To The Standard Library
A Proposal To Add Safe Integer Types To The Standard Library
Audience: SG-6
Contact: [email protected]
Date: 2016-02-16
Table of Contents
1. Motivation ....................................................................................................................................................... 1
2. Impact On the Standard ..................................................................................................................................... 2
3. Design Decisions .............................................................................................................................................. 2
4. Existing Implementations ................................................................................................................................... 3
5. Technical Specifications ..................................................................................................................................... 4
5.1. Type Requirements ................................................................................................................................. 4
Numeric<T> ........................................................................................................................................ 4
Integer<T> ........................................................................................................................................... 6
SafeNumeric<T> .................................................................................................................................. 7
6. Types .............................................................................................................................................................. 9
6.1. safe<T> ................................................................................................................................................ 9
Description .......................................................................................................................................... 9
Notation .............................................................................................................................................. 9
Template Parameters ............................................................................................................................. 9
Model of ............................................................................................................................................. 9
Valid Expressions ............................................................................................................................... 10
Header ............................................................................................................................................... 10
Example of use ................................................................................................................................... 10
7. Acknowledgements .......................................................................................................................................... 10
8. References ...................................................................................................................................................... 10
1. 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.
1
A Proposal to Add Safe Integer
Types to the Standard Library
3. Design Decisions
The template class is designed to function as closely as possible as a drop-in replacement for corresponding built-in integer types.
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.
Usage of a safe type in a binary expression is guaranteed to either return an arithmetically correct result or throw a standard
exception.
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.
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>
2
A Proposal to Add Safe Integer
Types to the Standard Library
#include <safe>
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.
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.
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.
4. Existing Implementations
This proposal is a simpler version / subset of the Safe Numerics library in development by Robert Ramey on the Boost Library
Incubator [http://rrsd.com/blincubator.com/bi_library/safe-numerics/?gform_post_id=426?]. It is compatible with this proposal but
it also includes:
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.
Without comment, here are implementations of libraries which are in some way similar to this proposal:
3
A Proposal to Add Safe Integer
Types to the Standard Library
5. Technical Specifications
5.1. Type Requirements
Numeric<T>
Description
A type is Numeric if it has the properties of a number.
More specifically, a type T is Numeric if there exists specialization of std::numeric_limits<T>. See the documentation for
standard library class numeric_limits. The standard library includes such specializations for all the primitive numeric types. Note
that this concept is distinct from the C++ standard library type traits is_integral and is_arithmetic. These latter fulfill the
requirement of the concept Numeric. But there are types T which fulfill this concept for which is_arithmetic<T>::value ==
false. For example see safe_signed_integer<int>.
Notation
Associated Types
std::numeric_limits<T> The numeric_limits class template provides a C++ program with information about various
properties of the implementation's representation of the arithmetic types. See C++ standard
18.3.2.2.
Valid Expressions
In addition to the expressions defined in Assignable [http://www.sgi.com/tech/stl/Assignable.html] the following expressions must
be valid. Any operations which result in integers which cannot be represented as some Numeric type will throw an exception.
Table 1. General
std::numeric_limits<T>.is_bounded true
4
A Proposal to Add Safe Integer
Types to the Standard Library
std::numeric_limits<T>.is_specialized true
os << t os &i
is >> t is &
-t T Invert sign
+t T unary plus - a no op
~ T complement
t - u V subtract u from t
t + u V add u to t
t * u V multiply t by u
t / u T divide t by u
t % u T t modulus u
5
A Proposal to Add Safe Integer
Types to the Standard Library
t = u T assign value of u to t
Header
#include <safe_numerics/include/concepts/numeric.hpp> [../../include/concept/numeric.hpp]
Models
int, safe_signed_integer<int>, safe_signed_range<int>, etc.
Integer<T>
Description
A type is fulls the requirements of an Integer if it has the properties of a integer.
More specifically, a type T is Integer if there exists specialization of std::numeric_limits<T> for which
std::numeric_limits<T>:: is_integer is equal to true. See the documentation for standard library class numeric_limits.
The standard library includes such specializations for all the primitive numeric types. Note that this concept is distinct from the C+
+ standard library type traits is_integral and is_arithmetic. These latter fulfill the requirement of the concept Numeric. But
there are types which fulfill this concept for which is_arithmetic<T>::value == false. For example see safe<int>.
6
A Proposal to Add Safe Integer
Types to the Standard Library
Refinement of
Numeric
Valid Expressions
In addition to the expressions defined in Numeric the following expressions must be valid.
Header
#include <safe_numerics/include/concepts/numeric.hpp> [../../include/concept/numeric.hpp]
Models
int, safe<int>, safe_unsigned_range<0, 11>, etc.
SafeNumeric<T>
Description
This holds an arithmetic value which can be used as a replacement for built-in C++ arithmetic values. These types differ from their
built-in counter parts in that the are guaranteed not to produce invalid arithmetic results.
Refinement of
Numeric
Notation
Symbol Description
t, u objects of types T, U
7
A Proposal to Add Safe Integer
Types to the Standard Library
Valid Expressions
s op t unspecified S invoke safe C++ operator op and return another SafeNumeric type.
t op s unspecified S invoke safe C++ operator op and return another SafeNumeric type.
s1 op s2 unspecified S invoke safe C++ operator op and return another SafeNumeric type.
prefix_op S unspecified S invoke safe C++ operator op and return another SafeNumeric type.
S postfix_op unspecified S invoke safe C++ operator op and return another SafeNumeric type.
s assign_op t S1 convert t to type S1 and assign it to s1. If the value t cannot be represented as an
instance of type S1, it is an error.
S(t) unspecified S construct a instance of S from a value of type T. f the value t cannot be represented
as an instance of type S1, it is an error.
is_safe<S> std::true_type type trait to query whether any type T fulfills the requirements for a SafeNumeric
or type.
std::false_type
T
static_cast<T>(s) convert the value of s to type T. If the value of s cannot be correctly represented
as a type T, it is an error. Note that implicit casting from a safe type to a built-in
integer type is expressly prohibited and should invoke a compile time error.
• Result of any binary operation where one or both of the operands is a SafeNumeric type is also a SafeNumeric type.
• Binary expressions which are not assignments require that promotion and exception policies be identical.
• Safe Numeric operators will NOT perform standard numeric conversions in order to convert to built-in types.
void f(int);
int main(){
long x;
f(x); // OK - builtin implicit version
safe<long> y;
f(y); // compile time error
return 0;
}
Complexity Guarantees
There are no explicit complexity guarantees here. However, it would be very surprising if any implementation were to be more
complex that O(0);
8
A Proposal to Add Safe Integer
Types to the Standard Library
Invariants
The fundamental requirement of a SafeNumeric type is that implements all C++ operations permitted on it's base type in a way
the prevents the return of an incorrect arithmetic result. Various implementations of this concept may handle circumstances which
produce such results differently ( throw exception, compile time trap, etc..) no implementation should return an arithmetically
incorrect result.
Header
#include <safe_numerics/include/concepts/safe_numeric.hpp> [../../include/concept/exception_policy.hpp]
Models
safe<T>
safe_signed_range<-11, 11>
safe_unsigned_range<0, 11>
safe_literal<4>
6. Types
6.1. 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
Template Parameters
T Integer [http:// The underlying type. Currently only integer types supported
en.cppreference.com/w/cpp/
types/is_integral]
Model of
Integer
SafeNumeric
9
A Proposal to Add Safe Integer
Types to the Standard Library
Valid Expressions
Implements all expressions defined by the SafeNumeric type requirements.
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> [../../include/safe_integer.hpp]
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;
}
7. Acknowledgements
This proposal is a simplified version of Safe Numeics library proposed for Boost. This effort was inspired by David LeBlanc's
SafeInt Library [http://safeint.codeplex.com] .
8. References
Omer Katz. SafeInt code proposal [http://boost.2283326.n4.nabble.com/SafeInt-code-proposal-td2663669.html] [http://
www.cert.org/secure-coding/publications/books/secure-coding-c-c-second-edition.cfm?] . Boost Developer's List [https://
groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-proposals] . Katz
David LeBlanc. Integer Handling with the C++ SafeInt Class [https://msdn.microsoft.com/en-us/library/ms972705.aspx] .
Microsoft Developer Network [https://www.cert.org] . January 7, 2004. LeBlanc
10
A Proposal to Add Safe Integer
Types to the Standard Library
Robert C. Seacord. INT32-C. Ensure that operations on signed integers do not result
in overflow [https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed
+integers+do+not+result+in+overflow] . Software Engineering Institute, Carnegie Mellon University [https://
www.cert.org] . August 17, 2014. INT32-C
11
12