Operating on Byte data types

cugone

Newcomer
Joined
Apr 30, 2008
Messages
19
Maybe I'm just crazy but for some reason, the VB documentation says that a Byte "Holds unsigned 8-bit integers ranging in value from 0 through 255", yet when I do something like:

Code:
Dim small as Byte = 0
small += 1

VB complains up a storm. Is there simpler way to do simple increments/decrements or addition/subtraction to Bytes rather than:

Code:
Dim small as Byte = 0
small += Convert.toByte(1)

/everytime/?

It's smart enough to truncate fractions, yet, it can't figure that 0000 0000 0000 0000 0000 0000 0000 0001 should be converted to 0000 0001. Sheesh.

Done venting now. :P
 
Option Strict On

2005 version works also.

Diesel, JumpyNET, try again with Option Strict On, and you'll see what cugone is complaining about. Just another of those annoying quirks of VB.NET I guess. Of course you can get around it by turning Option Strict Off, but you shouldn't have to.
 
Re: Option Strict On

Well, VB.NET is trying to be helpful when in 'Option Strict Off' here, and I think that it is. In most other cases, though, you really do want to be forced to make your casts explicit, so 'Option Strict On' really is pretty much a necessity.

The same thing happens in C#, although not with the '+=' or '++' operator. The problem is that the '+' operator is defined for integer, but not for byte or short, so byte and short operands are upcasted to integer, added together, and then returned as an integer. So when returning the result back to the byte it needs to be explicitly cast back:

On the other hand, the '++' and '+=' operators are overloaded to accept and return byte:

Code:
byte b = 0;

b++;         // <-- Ok
b += 1;      // <-- Ok
b = b + b;   // <-- Compile time error!

The compiler's complaint on the last line is:

"Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)"

And so we're required to use:
Code:
b = (byte)(b + b);

I don't see why the '+' operator could not be overloaded in a future version in order to directly handle byte and short data types (instead of upcasting). It would seem to make more sense that '+' operate by the same rules as '+=' and '++'.

I guess the problem with trying to change this the issue of overflow, esp. when we could have two flavors: unchecked or checked. Still, I think it's an uncomfortable situation that '++' and '+=' are operating differently, allowing implicit casts whereas '+' does not.
 
Last edited:
Re: Option Strict On

Actually, while we're on the subject... how is it that the following is legal in C# without an explicit cast:

Code:
byte b = 0;
b = 1;

Or this:
Code:
byte b = 0;
b = 1 + 1;

But not this:
Code:
byte b = 0;
b = b + b;   // <-- Compile time error.

Kinda weird, eh? Seems to be some compiler "help" in some circumstances, but not in others. I'm wondering what the rule is here. (Is there a rule?)
 
Compiler evaluation

Kinda weird, eh? Seems to be some compiler "help" in some circumstances, but not in others. I'm wondering what the rule is here. (Is there a rule?)

I would hope that the compiler is advanced enough to pre-evaluate 1 + 1 and replace it with 2, which it knows will not overflow a byte. It is much more complex to determine whether b + b would overflow.
 
Re: Compiler evaluation

Ok, fair enough...

But 'b + b' is a compile time error, not a run-time error, so this still leaves us with the fact that '++' and '+=' appear to be explicitly overloaded for 'byte' and 'short' whereas '+' upcasts to integer instead, but then you get snagged when assigning the return value.
 
Last edited:
A demonstration

After some thought, I came up with a reasoning for upcasting to int. Consider the following code:

C#:
//Addition 1
byte b = 250;
short s = (short) (b + b);
Console.WriteLine("s = {0}", s);

//Addition 2
s = (short) (byte) (b + b);
Console.WriteLine("s = {0}", s);

The point is, the addition operator by itself has no knowledge of what its return value will be used for. The second addition here simulates an addition operator which adds two bytes together and returns a byte. If you run the code you'll see that the output is incorrect - 244, rather than 500 - due to the truncation.

It follows that the simple addition operator should always treat its operands as 32 bit values and return a 32 bit value. The ++ and += operators know the data type of their assignee, so can explictly cast to that type.
 
Re: A demonstration

Yeah, I think you got it. And, and unfortunately, this would be a reverse-compatibility issue if they changed it.

However, one could envision a world where the '+' operator is overloaded for 'byte' and 'short', in that case:
Code:
byte b = 250;
b = b + b;

would return 244 (or throw an exception if checked), instead of returning 500. If you wanted to get the behavior shown in your 'short s = (short) (b + b);' example then one would have to explicitly cast at least one of the operands:
Code:
byte b = 250;
short s = (short)b + b;

I really think that this is the way it "should" be, the more I think about it... but there would be reverse-compatibility issues if they did this now, as highlighted by your example.

My guess as to why they do it this way is that this would take *extra* steps to execute overflow behavior for 8 bits or 16 bit types, which wouldn't overflow when using native 32 bit arithmetic. Still, the "explicit cast approach" would allow one to force 32 bit calculations -- but it would take extra coding (an explicit cast) to force the more efficient execution.

This brings up something related though... How does the following execute on a 64 bit machine?

Code:
int i = int.MaxValue;
long l = i + i;

I don't have access to a 64 bit machine, but I'll guess that it would have to assign -2 to the 'long l' value, right? Otherwise there would be massive compatibility issues depending on whether the code is running on a 32 bit or 64 bit machine. But this would also mean that an "artificial overflow" concept (extra code checks) would be in force here for 'int + int', but not for 'byte + byte' or 'short + short'.

Kind of interesting...
 
Last edited:
Back
Top