Negating a short?
Dennis
dkorpel at gmail.com
Wed Nov 6 00:00:48 UTC 2024
On Tuesday, 5 November 2024 at 20:29:08 UTC, Andy Valencia wrote:
> I still see:
>
> tst15.d(6): Error: cannot implicitly convert expression
> `-cast(int)s` of type `int` to `short`
That's right, it only removes the deprecation that requires a
double cast to fix, but you still need an explicit cast to
truncate the result of `-s` (which got promoted to `int`) back to
a `short`, unless the compiler can prove at compile time it will
always fit in 16 bits. This analysis is called Value Range
Propagation (VRP) in the specification:
https://dlang.org/spec/type.html#vrp
For example, this compiles:
```D
void f(short s)
{
short t = -s / 2; // will always fit
short u = -s % 1024; // will always fit
}
```
In your example, you get an error because:
- VRP doesn't do data flow analysis: it only looks at the current
expression without looking at variable assignments that came
before it. It doesn't see the value of `s` will always be -5 in
that case (though in your actual code there's not a hardcoded
constant like -5 so it wouldn't even matter).
- Then, considering `s` could be anything from -32768 to 32767,
there's a chance of integer overflow because -(-32768) = 32768
which overflows to -32768 when cast to a short.
To signal that this possible overflow is okay, an explicit cast
is needed:
```D
s = cast(short) -s;
```
You can also use an assignment operator, which allows overflow
without explicit cast:
```D
s *= -1;
```
Which integer conversions are implicit and which ones must be
explicit is somewhat controversial. In this case, the compiler
can be annoyingly strict, but there's also cases where the
compiler is surprisingly lenient: like implicitly converting
`bool` / `char` to `int`, or implicitly converting `int` to
`uint` (where negative ints implicitly overflow, a common source
of bugs!). There have been proposals to change the behavior, but
there's often disagreement on the pros and cons of
implicit/explicit. On top of that, existing D code shouldn't be
broken, and remain consistent with C. (D is designed so that
expressions that are the same as C behave the same as C) So it's
hard to design a solution for this.
More information about the Digitalmars-d-learn
mailing list