| |
 | Posted by Jonathan M Davis in reply to pineapple | Permalink Reply |
|
Jonathan M Davis 
Posted in reply to pineapple
| On Monday, September 05, 2016 00:26:01 pineapple via Digitalmars-d-learn wrote:
> This program does not compile.
>
> Error: cannot implicitly convert expression (cast(int)x -
> cast(int)x) of type int to ubyte
>
> void main(){
> ubyte x;
> x = x - x;
> }
>
> I don't even know what to say. Who thought this behavior was a good idea?
It's exactly the same behavior you get in C/C++ except that they allowing narrowing conversions without a cast, whereas D does not. All arithmetic for integral types smaller than int are done as int. So, the result of x - x is int. And in C/C++, you could happily assign it back to x without realizing that the arithmetic had been done as int, but because D disallows narrowing conversions without a cast (just like C# and Java do), assigning it back then results in an error. And yes, it can be annoying, but it helps catch bugs.
Fortunately, D has VRP (Value Range Propagation), which means that if the compiler can determine that the result of an arithmetic operation would definitely fit in the type that it's assigned to, then there is no error even if it involves a narrowing conversion. So, something like
ubyte x = 19 + 7;
will compile. Unfortunately, the compiler only looks at the current expression rather than doing true control flow analysis when in does VRP. So, something like
ubyte x = 19;
ubyte y = x + 7;
won't compile without adding a cast to the second line, and in practice, I don't think that VRP helps much. It's still better than nothing though, and at some point, it may be expanded to cover multiple statements.
Ultimately, this is just one of those annoyances that comes as a side effect of the compiler trying to prevent a certain class of bugs - in this case, requiring that narrowing conversions use a cast.
- Jonathan M Davis
|