why does adding 2 bytes together result in an int?

M

moondaddy

my understanding is that the max value of a byte is 255. Therefore, why
does the following code get a compile error?

byte val1 = 10;
byte val2 = 23;
byte ttl;
ttl = val1 + val2; //this line wont compile

compile error: Cannot implicitly convert type 'int' to 'byte'.

val1 + val2 = 33 which is still in the range of a byte. therefore, why do I
need to convert ttl into an int?

Thanks.
 
L

Larry Lard

moondaddy said:
my understanding is that the max value of a byte is 255. Therefore, why
does the following code get a compile error?

byte val1 = 10;
byte val2 = 23;
byte ttl;
ttl = val1 + val2; //this line wont compile

compile error: Cannot implicitly convert type 'int' to 'byte'.

val1 + val2 = 33 which is still in the range of a byte. therefore, why do I
need to convert ttl into an int?

What's 128 + 128 ?
 
V

Vadym Stetsyak

Hello, moondaddy!

m> byte val1 = 10;
m> byte val2 = 23;
m> byte ttl;
m> ttl = val1 + val2; //this line wont compile

m> compile error: Cannot implicitly convert type 'int' to 'byte'.

m> val1 + val2 = 33 which is still in the range of a byte. therefore, why
m> do I need to convert ttl into an int?

IMO the trouble here is that IL opcode 'add' doesn't use byte ( int8 ) type to perform additions. That is why the result value is int32.

if you will write

ttl = (byte)(val1 + val2)
then 'conv.u1' opcode is added that converts the value to neede type ( int8 or byte )...

--
Regards, Vadym Stetsyak
www: http://vadmyst.blogspot.com
 
C

Carlo Stonebanks

I know that this was a discussion on code optimisation and the technology
behind .NET, but I think that explicit casting in this case is a good idea
as a matter of principle.

Performing math on a byte is an exceptional affair, so casting makes you
look carefully at code that could very quickly run into trouble. Better yet,
it has the added benefit of creating self-documenting code - you'd have to
be a real ninny not to know why the code's author was casting a byte to and
from an int.

IMHO explicit casting makes the value's severe limitation obvious to other
programmers maintaining your code (and to yourself in five years when you
forgot what you were doing!)

Carlo
 
K

Kevin Spencer

This is because the devleopers of the platform have decided that the return
type of the + operator for the byte type should be an integer. That makes
sense, because (1) the return type must be the same for all operations, and
(2) there is no guarantee that adding 2 or more byte values together will
not overflow the size of a byte, which is 256.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A brute awe as you,
a Metallic hag entity, eat us.
 
J

Jon Skeet [C# MVP]

Kevin Spencer said:
This is because the devleopers of the platform have decided that the return
type of the + operator for the byte type should be an integer.

Not quite. There *aren't* any + operators for the byte type. These are
the integer addition operators:

int operator +(int x, int y);
uint operator +(uint x, uint y);
long operator +(long x, long y);
ulong operator +(ulong x, ulong y);

When it looks like you're adding two bytes, you're actually implicitly
converting each of them to an integer, then adding the two integers
together.
 
K

Kevin Spencer

Okay, Jon, *be* that way. ;-)

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
A brute awe as you,
a Metallic hag entity, eat us.
 
N

Nick Hounsome

moondaddy said:
my understanding is that the max value of a byte is 255. Therefore, why
does the following code get a compile error?

byte val1 = 10;
byte val2 = 23;
byte ttl;
ttl = val1 + val2; //this line wont compile

compile error: Cannot implicitly convert type 'int' to 'byte'.

val1 + val2 = 33 which is still in the range of a byte. therefore, why do
I need to convert ttl into an int?

There is no really good reason.

What Jon said about the IL opcodes is true but irrelevant - the compiler
could just cast the result back to byte for you.

What others said about 128 + 128 is true but inconsistent - the same
arguments could be applied to int or long.

I agree that it is a total pain and either an oversight or excess nannying
by MS but that's the way that it is.

On the plus side it would break no code to change it so MS might do it if
enough people complain.

P.S. It's the same for short - but who uses short?
 
J

James Park

Nick Hounsome said:
What others said about 128 + 128 is true but inconsistent - the same
arguments could be applied to int or long.

I agree that it is a total pain and either an oversight or excess nannying
by MS but that's the way that it is.

There was a good amount of healthy debate at The Old New Thing:

http://blogs.msdn.com/oldnewthing/archive/2004/03/10/87247.aspx

I think the best reason stated was for consistency with C++, as weak as that
may or may not be.
On the plus side it would break no code to change it so MS might do it if
enough people complain.

byte firstNumber = 128;
byte secondNumber = 128;
int sum = firstNumber + secondNumber;

I believe sum would equal 256 as things are now and 0 if byte addition was
introduced.
 
N

Nick Hounsome

James Park said:
There was a good amount of healthy debate at The Old New Thing:

http://blogs.msdn.com/oldnewthing/archive/2004/03/10/87247.aspx

I think the best reason stated was for consistency with C++, as weak as
that may or may not be.


byte firstNumber = 128;
byte secondNumber = 128;
int sum = firstNumber + secondNumber;

I believe sum would equal 256 as things are now and 0 if byte addition was
introduced.

Good point. I was thinking of "byte sum = firstNumber + secondNumber;"

Allowing assignment of int to byte without a warning would obviously be
unacceptable so I suppose that we just have to live with it although I don't
like the inconsistency:

In x1+x2
2 bytes get promoted to ints.
2 shorts get promoted to ints even though overflow seems rather unlikely in
this case.
2 ints don't get promoted to longs even though they can overflow just as
bytes can.
2 longs couldn't be promoted to anything reasonable even if we wanted to.
 
J

Jon Skeet [C# MVP]

Nick Hounsome said:
There is no really good reason.

There is: performance.

Converting it back to a byte would be a significant (and then
unavoidable) performance hit which you often wouldn't want. This way,
you *can* force the conversion back to a byte, but you don't get it if
you don't want it.
On the plus side it would break no code to change it so MS might do it if
enough people complain.

It would break code. If you had the following overloads:

void SomeMethod (int)
void SomeMethod (byte)

then:

byte a = 10;
byte b = 20;

SomeMethod (a+b);

Current behaviour is to call SomeMethod(int). Changing to a give an
operator of byte +(byte, byte) would change the call to
SomeMethod(byte).
 
M

moondaddy

Thanks to ALL.

This thread was very enlightening. At first it just didn't make sense that
they would allow you to add to ints together and potentially make an
overflow, but not 2 bytes. Hmmmm.
 
S

Scott C

Nick said:
There is no really good reason.

What Jon said about the IL opcodes is true but irrelevant - the compiler
could just cast the result back to byte for you.

What others said about 128 + 128 is true but inconsistent - the same
arguments could be applied to int or long.

I agree that it is a total pain and either an oversight or excess nannying
by MS but that's the way that it is.

On the plus side it would break no code to change it so MS might do it if
enough people complain.

P.S. It's the same for short - but who uses short?
I second the motion.

Int32 whoops = Int32.MaxValue + 1;

Scott
 
W

Willy Denoyette [MVP]

| Nick Hounsome wrote:
| > | >> my understanding is that the max value of a byte is 255. Therefore,
why
| >> does the following code get a compile error?
| >>
| >> byte val1 = 10;
| >> byte val2 = 23;
| >> byte ttl;
| >> ttl = val1 + val2; //this line wont compile
| >>
| >> compile error: Cannot implicitly convert type 'int' to 'byte'.
| >>
| >> val1 + val2 = 33 which is still in the range of a byte. therefore, why
do
| >> I need to convert ttl into an int?
| >
| > There is no really good reason.
| >
| > What Jon said about the IL opcodes is true but irrelevant - the compiler
| > could just cast the result back to byte for you.
| >
| > What others said about 128 + 128 is true but inconsistent - the same
| > arguments could be applied to int or long.
| >
| > I agree that it is a total pain and either an oversight or excess
nannying
| > by MS but that's the way that it is.
| >
| > On the plus side it would break no code to change it so MS might do it
if
| > enough people complain.
| >
| > P.S. It's the same for short - but who uses short?
| >
| >
| I second the motion.
|
| Int32 whoops = Int32.MaxValue + 1;
|


Int32 whoops = Int32.MaxValue + 1;
produces -> error: CS0220 at compile time
and integer overflows will throw when checked mode is enabled.
Is there something else you are looking at?

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top