Boost logo

Boost :

Subject: Re: [boost] updated version of safe integer library
From: Robert Ramey (ramey_at_[hidden])
Date: 2016-02-03 18:18:42


On 2/3/16 12:26 PM, Noah wrote:
> On 12/22/2015 9:09 AM, Robert Ramey wrote:
>
>> Of course I'm interested any feedback and/or observations anyone want's
>> to offer.
>
> Hey there,
>
> First let me say that I haven't tried out your library yet, but from
> what I've read I think it's great.
>
> So I stumbled upon the comments in your default constructor:
>
> // default constructor
> constexpr explicit safe_base() {
> // this permits creating of invalid instances. This is inline
> // with C++ built-in but violates the premises of the whole
> library
> // choice are:
> // do nothing - violates premise of he library that all safe
> objects
> // are valid
> // initialize to valid value - violates C++ behavior of types.
> // add "initialized" flag. Preserves fixes the above, but doubles
> // "overhead"
> // still pending on this.
> }
>
> We've been having this debate over in the "[smart_ptr] ...

This is a fundamental question. The library has multiple goals
a) safety as requirement that cannot be worked around.
b) minimal runtime overhead
c) drop in replacement for intrinsic integers.
d) make the library idiot simple to use.

These goals conflict in some cases. In most of those I've been
able resolve these conflicts to my satisfaction. In many cases
these conflicts are resolved by the usage of a policy class
which permits the library user to make the trade off.

But in the case of construction I couldn't really find
a resolution in the bounds of the time that I was willing
to spend on it. So I punted for later. I don't think it's
insurmountable, it just requires more thought than first
meets the eye. I'm not motivated to spend much more time
with the library unless I get feed back indicating that
people are interested in it are actually using it.

> So for
> example safe<int> might have default initialization and almost_safe<int>
> might not. And even in the case where there is default initialization,
> there's the question of whether you should still require that the value
> be explicitly set before the first use. (This can be checked for and
> enforced in debug mode.)

So you're appreciating the possibilities and the trade-offs.
Right now I don't have a lot to add to the comment. Sometimes
a little feedback from users is all that's needed to make
the resolution obvious.

> While writing some security conscious applications I've been
> incidentally writing a small library of safer substitutes for some C++
> data types (https://github.com/duneroadrunner/SaferCPlusPlus). Among the
> substitutes it includes are those for int and size_t. Rather than doing
> comprehensive range checking like your library does, my types just do
> range checking only where I have the feeling it's particularly important
> and worth the performance cost. That's basically just when converting to
> different integer types, and in operator-=() for size_t.

It sounds like it's the same library. I just pursued it to the bitter
end where TMP takes you. This makes it a lot more complex - but
guarantees that every operation checked if and only if this
checking is necessary.

Turns out that using ranged types can make runtime checking unnecessary
in many or most cases. The documentation shows many examples where
no runtime checking is necessary. In cases where it necessary, small
changes in user code can make runtime checking unnecessary - all
this while preserving safety. Also there are examples where
one can use the library to trap at compile time any operation
which could possible require a runtime check. This would
point to minor changes (e.g. changing a datatype) so that
one would absolutely know that no operation can fail at
runtime - thereby making the inclusion of exception
handling code unnecessary. It's all in the examples
in the documentation.

> Would your library support limiting it's range checks for performance reasons?

I'm not sure what you mean here. range checks only included
when it's possible to generate an error. So
safe<int8_t> i;
safe<int16_t> j;
j = i; // zero runtime overhead
int16_t k;
k = i // zero runtime overhead
int8_t l;
i = l // zero runtime overhead
j = l; // zero runtime overhead

>
> I guess the goal of my library is roughly to enable C++ programmers to,
> if they choose, write their code with "language safety" approaching that
> of Java's.

I think our libraries have the same goal. I think I just invested more
time in mine.

> But your library suggests that C++ could maybe even surpass
> Java as the choice for safe, secure and correct applications.

I don't know about java nor what it provides. When using
this library for one's integer types, every operation is guaranteed
to do one of the following:

a) return an arithmetically correct result.
b) trap with a compile time error
c) throw an exception

> So I
> wonder about the motivating cases for your library. I mean, was it
> designed to address specific use cases, or is it meant to be used more
> generally?

The statement immediately above describes it's scope.

The documentation includes seven examples of situations where the
library might be useful.

I think your library is so novel to me, I don't have a good
> grasp on the range of application types that might end up using it.

again - the scope is very general. It's intended as a drop-in
replacement for any integer type in any program which

a) must be demonstrably correct

this excludes usage of unchecked operations

b) must detect every user error

requires exhaustive checking - like user input, copies, implicit
conversions etc.

c) must be efficient as possible subject to the constraints above

this excludes interpreter like solutions - most of which aren't safe anyway.

d) must have readable code which can be verified to execute
the desired algorithm.

This excludes subroutine libraries with functions like
add(int j, int i), etc. . The requiring re-writing the whole program to
use these special functions rather than using C/C++ arithmetic
expressions. Manually "compiling" C/C++ expressions in terms of these
functions is tedious, time consuming and error prone. This currently the
only recommendation by experts in writing safety critical code.

> I might guess though, that some of the applications using your library to
> ensure against out of range arithmetic results might also benefit from
> using something like my library to ensure against,

 From what you've said, I think the libraries address the same problem.
I just think I spent more time on mine. I didn't do it on someone
else's payroll so I could afford (or not) to spend whatever it takes
to take to logical end point.

> for example, invalid memory access or

This is not addressed by the safe_integer library

> out ofrange vector element access.

There is an example which illustrates this.

> I guess what I'm wondering is, whether you think your library is an
> intrinsically independent one addressing a specific domain, or
> ultimately should be part of a larger set of tools for facilitating
> safety/security/correctness in C++?

Everything can be part of a larger set of tools. Writing safe,
efficient, guaranteed correct programs requires additional tools besides
safe integer

a) safe float - This project is underway - but i haven't heard much
progress lately.

b) dimensions and units - uses the type system to enforce diminsional
analysis and correct conversion between units systems. This is
indispensable for writing correct engineering/scientific programs
but almost never used. Boost has a good library for doing this, but
unfortunately, the documentation is so opaque as to make the library all
but unusable.

c) thread, exception and memory allocation safety. These problems
are already well addressed by C++ compiler and libraries.

C++ is suited like no other language To write these tools.

But there is one more thing ...

Writing correct code is not considered a major problem by most
programmers and organizations which depend on code. Code that works
most of the time is considered good enough. In spite of the current
problems like unintended acceleration, failures on ABS systems, blown
missile launches, crashing mars probes - this is not considered a
problem. Two papers were submitted to CppCon 2015 on safe integers (one
by me and one on bounded integers - similar topic) and neither were
considered interesting to other reviewers to potential attendees. I
suspect they are right - and that's a problem - a huge problem. This
problem affects all computer languages. There has never been an
industrial strength solution to this problem - until now. And the
response has been .... I've requested twice that this library be added
to the boost review queue - no action. I've requested twice that a
simpler version of this library which was formulated as a proposal be
added to the list of standard library proposals - again - no actions.

It's just not important to most of the world. I'm not bitter (though it
might seem that I am - I'm really not). I'm just disgusted. (which is
an entirely different thing.

OK - I've had my fun, I'll let you go now.

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk