[OT] The Usual Arithmetic Confusions

Siarhei Siamashka siarhei.siamashka at gmail.com
Thu Feb 3 02:25:34 UTC 2022


On Thursday, 3 February 2022 at 01:05:15 UTC, Walter Bright wrote:
> On 2/2/2022 3:37 PM, Adam Ruppe wrote:
>> The value range propagation only works inside single 
>> expressions and is too conservative to help much in real code.
>
> I find it works well. For example,
>
>     int i;
>     byte b = i & 0xFF;
>
> passes without complaint with VRP.

No, it's doesn't pass: `Error: cannot implicitly convert 
expression i & 255 of type int to byte`.

> As does:
>
>     ubyte a, b, c;
>     a = b | c;

But `a = b + c` is rejected by the compiler. Maybe I'm expecting 
modular wrap-around arithmetic here? Or maybe I know the possible 
range of `b` and `c` variables and I'm sure that no overflows are 
possible? But the compiler requires an explicit cast. Why is it 
getting in the way?

Also if the type is changed to `uint` in the same example, then 
the compiler is suddenly okay with that and doesn't demand 
casting to `ulong`. This is inconsistent. You will probably say 
that it's because of integer promotion and 32-bit size is a 
special snowflake. But if the intention is to catch bugs at the 
compilation stage, then adding two ubytes together and adding two 
uints together isn't very different (both of these operations can 
potentially overflow). What's the reason to be anal about ubytes?

The other modern programming languages can catch arithmetic 
overflows at runtime. And allow to opt out of these checks in 
performance critical parts of the code.


More information about the Digitalmars-d mailing list