www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is this behavior and how do I disable or get around it?

reply pineapple <meapineapple gmail.com> writes:
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?
Sep 04 2016
next sibling parent ak <ak abc.de> writes:
On Monday, 5 September 2016 at 00:26:01 UTC, pineapple 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?
x = cast(ubyte)(x - x);
Sep 04 2016
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
On Monday, 5 September 2016 at 00:26:01 UTC, pineapple 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?
See the sections 'Integer Promotions' and 'Usual Arithmetic Conversions' in the docs at [1]. [1] http://dlang.org/spec/type.html#integer-promotions
Sep 04 2016
prev sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
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
Sep 04 2016