5

I've tried

 module Program
 {
  Main() : void
  { mutable x : byte = 0B;
    mutable y : byte = 0B;  
    x++;
    //y = x + 1;
    //y = x + 1B;
    //def one:byte=1;//   x = x + one;
  }
 }

No matter which one I try, I get the following error message.

Error 1 expected byte, got int in assigned value: System.Int32 is not a subtype of System.Byte [simple require]

Only way I've found that works is

    y = ( x + 1 ):>byte

Which is bit of faff, just to add one.

Why is this? and Is there a better (read shorter way)?

Adam Speight
  • 630
  • 9
  • 21
  • 1
    I don't use nermerle, but it sounds like a "*type widening*" issue -- what is the return type of `byte + int`? What of `byte + byte`? C# is similar: `byte x = 0; x = x + 1` will also not compile. (C# will actually work okay with `x += 1` and `x++`, but it may be the case that these are expanded in nemerle.) –  Jul 10 '11 at 21:09
  • byte + int = int (int is the dominant type). `byte + byte` is the unexpected return type of an int – Adam Speight Jul 10 '11 at 21:58

4 Answers4

8

As in C#, the result of the sum of a byte and a byte in Nemerle is an int. However, unlike C#, Nemerle tries to keep the core language as compact as possible, keeping all of the syntax sugar in the standard macro library. In this spirit, the += and ++ operators are macros that are translated into regular addition.

To answer your question, (x + 1) :> byte is the way to do it. It actually is not all bad, because it lets the reader of your code know that you are aware of the danger of overflow and take responsibility for it.

Still, if you feel strongly about it, you can easily write your own += and ++ macros to perform the cast. It would only take a few lines of code.

Don Reba
  • 12,756
  • 3
  • 41
  • 55
2

It is because the CLR defines only a limited number of valid operands for the Add IL instruction. Valid are Int32, Int64, Single and Double. Also IntPtr but that tends to be disabled in many languages.

So adding a constant to a byte requires the byte to be converted to an Int32 first. The result of the addition is an Int32. Which doesn't fit back into a byte. Unless you use a bigger hammer. This is otherwise healthy, the odds that you overflow Byte.MaxValue are pretty large.

Note that there are languages that automatically cast, VB.NET is one of them. But it also automatically generates an OverflowException. Clearly not the one you are using, nor C#. This is a perf choice, the overflow test is not that cheap.

Hans Passant
  • 873,011
  • 131
  • 1,552
  • 2,371
  • `y = if(x<255){x + 1}else{255};` is not too hard to write. So take it C# is implicitly widening casting a byte to int (secretly), which to be is bit against the spirit type safety. You'd think you could do simple additions with the "basic" types without the casting. – Adam Speight Jul 10 '11 at 21:51
  • *All* languages widen the byte. They have to, there is no add operator that takes a byte. This was key to my answer. Your workaround is questionable, I would throw OverflowException but will put up with 0. 255 makes no sense. – Hans Passant Jul 10 '11 at 22:14
  • Not if you want bounded values. – Adam Speight Jul 10 '11 at 22:41
  • That's just a pretty name for "bug". No way that the CLR designers could ever commit to *that* behavior. An Add that doesn't add anything is a litany of bug reports. You are free to inject the behavior yourself. – Hans Passant Jul 10 '11 at 22:56
1

Disclaimer: I don't know Nemerle, but I'm assuming it behaves similar to C# in this regard.

There is a better and shorter way: don't use bytes.

Why are you using them in the first place? Most of the time, computations with ints are faster than using bytes, because today's computers are optimized for them.

svick
  • 214,528
  • 47
  • 357
  • 477
  • can you explain why int based calculations are faster then byte based ones? – platon Jul 10 '11 at 21:09
  • 1
    @svick Doh! I would never have thought of that. (sarcasm). I'm using bytes. You can add one to byte in C# and it works, why not Nemerle? – Adam Speight Jul 10 '11 at 21:10
  • 1
    @Adam, you can't do that in C#. – svick Jul 10 '11 at 21:13
  • found the developer with no contact to hardware. working with bytes and stuff becomes important when you have an interface to hardware which expects stuff like that. – Blechdose Feb 05 '20 at 16:33
0

This is what the type system does. Additions upgrade values to ints and then performs the operation resulting in a int. Also have thought what should happen if starting value was 255?