
2015-12-11 17:21 GMT+01:00 Robert Ramey
On 12/11/15 7:07 AM, Andrzej Krzemienski wrote:
Hi Robert,
It is great to see this library getting into Boost. It fills an important gap, but it is only after a long while that I realized that, because the introductory part of the documentation does not stress it enough, and in fact it misled me a bit.
I'm not sure if you're referring to the documentation as it was when you posted your review or the documentation in it's current state. When I read you're review I realized that I hadn't clearly isolated the concept of undefined behavior from that if incorrect arithmetic behavior. I reworked a lot of the documentation based on your review.
Also as I worked on the package it became clear to me that I had to be more ambitious to make the impact I wanted.
Yes, I am referring to the rewritten documentation. I observe that it has changed significantly.
My understanding is that safe<int> represents a high level abstraction of an integral number from mathematics: unlike raw type int, which represents a set of allowed operations on the underlying processor.
Very well put. I'll work that in somewhere.
You could say that raw type 'int' is only needed to efficiently implement
higher level abstractions, like BigInt or safe<int> -- the two only differ in trade-offs between efficiency and the range of values they can represent.
Again correct. The key concept is that our machines don't implement arithmetic. It's up to us to find a way to make them do it. Until we do, we'll be in a continuous battle to reconcile the differences between the arithmetic we think about and the bit manipulation that our machines do.
I was missing this in the introduction. Instead I got a somewhat negative
impression that the goal of the library is to turn any UB into throwing exceptions (and thereby prevent any UB-based static analysis from detecting programmer errors).
That wasn't all that in accurate. When I started the library, I was just thinking I needed a hack to reduce my bug count. I figured I could make a small class which would do the job and that it take a couple of days to make a cool little class.
That was three years ago.
As I started to patch up corner cases, I came to understand that one had to grab the stick from the other end. That is, instead of trying to patch up C/C++ arithmetic to make it less error prone, start with arithmetic and "re-implement" it in terms of the operations that computer hardware actually implements. Add to this two key requirements:
a) do not ignore cases where the underlying hardware cannot produce a correct result.
b) implementation must be as fast as possible
I was missing such strong statement from the first page: "This library does not avoid some UB: it provides a higher level abstraction than 'int' even if it has the same interface".
I would like to see the library in Boost, although I must admit the other
parts do not sound that compelling as safe<int>.
what other parts?
1. safe_unsigned_range -- while I understand the idea behind it, I don't think I would be inclined to use it. And also, I believe it addresses a different problem, and could be handled by another library, like: http://rk.hekko.pl/constrained_value/ 2. safe<unsigned int> -- this looks suspicious. Unlike signed int, unsigned int does not overflow. It is meant to represent the modulo arithmetic with well defined result for any input values. If I do not want modulo arithmetic, I would rather go with safe<int> than safe<unsigned>. 3. The docs mention a possible extension for safe<float>. I do not know what that would mean. In the case of safe<int> I know what to expect: you trap when I try to build value greater than INT_MAX or smaller than INT_MIN: nothing else could go wrong. But in case of float: do you trap when I want to store: safe<float> ans = safe<float>(1.0) / safe<float>(3.0); ?? 1/3 does not have an accurate representation in type float. But if you trap that, you will be throwing exceptions all the time. So is it only about overflow? Regards, &rzej