+10  A: 

It's not just subtraction, there simply exisits no short (or byte/sbyte) arithmetic.

short a = 2, b = 3;
short c = a + b;

Will give the error that it cannot convert int (a+b) to short (c).

One more reason to almost never use short.

Additional: in any calculation, short and sbyte will always be 'widened' to int, ushort and byte to uint. This behavior goes back to K&R C (and probaly is even older than that).

The (old) reason for this was, afaik, efficiency and overflow problems when dealing with char. That last reason doesn't hold so strong for C# anymore, where a char is 16 bits and not implicitly convertable to int. But it is very fortunate that C# numerical expressions remain compatible with C and C++ to a very high degree.

Henk Holterman
It should be noted that this is part of the C#/CLI standard.
sixlettervariables
A: 

I think its done automatically done to avoid overflow,

lets say you do something like this.

Short result = Short.MaxValue + Short.MaxValue;

The result clearly wouldn't fit in a short.

one thing i don't understand is then why not do it for int32 too which would automatically convert to long???

Keivan
It's not done to prevent overflow, more to discourage inefficient code. And it's inherited from C/C++
Henk Holterman
+6  A: 

All operations with integral numbers smaller than Int32 are widened to 32 bits before calculation by default. The reason why the result is Int32 is simply to leave it as it is after calculation. If you check the MSIL arithmetic opcodes, the only integral numeric type they operate with are Int32 and Int64. It's "by design".

If you desire the result back in Int16 format, it is irrelevant if you perform the cast in code, or the compiler (hypotetically) emits the conversion "under the hood".

Also, the example above can easily be solved with the cast

short a = 2, b = 3;

short c = (short) (a + b);

The two numbers would expand to 32 bits, get subtracted, then truncated back to 16 bits, which is how MS intended it to be.

The advantage of using short (or byte) is primarily storage in cases where you have massive amounts of data (graphical data, streaming, etc.)

P.S. Oh, and the article is "a" for words whose pronunciation starts with a consonant, and "an" for words whose pronunciated form starts with a vowel. A number, AN int. ;)

kek444
+1 Nice answer. (And deserves a bonus for your answer on the indefinite article. ;-))
Mike Rosenblum
Excellent, Kek444. You should add your answer to this related question (http://stackoverflow.com/questions/941584/byte-byte-int-why). I would definitely upvote it.
Robert Cartaino
Thanks for the positive comments, will do.
kek444
Small nitpick, they are "widened" rather than "rounded up". Integers don't require rounding to go to larger sizes, floats do.
sixlettervariables
Yes, thanks, you are right, what I meant was that the number of bits was rounded up, while the number itself is widened. I'll clear it up.
kek444
+2  A: 

The other answers given within this thread, as well as the discussions given here are instructive:

(1) Why is a cast required for byte subtraction in C#?

(2) byte + byte = int… why?

(3) Why is a cast required for byte subtraction in C#?

But just to throw another wrinkle into it, it can depend on which operators you use. The increment (++) and decrement (--) operators as well as the addition assignment (+=) and subtraction assignment (-=) operators are overloaded for a variety of numeric types, and they perform the extra step of converting the result back to the operand's type when returning the result.

For example, using short:

short s = 0;

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

Using byte:

byte b = 0;

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

If they didn't do it this way, calls using the increment operator (++) would be impossible and calls to the addition assignment operator would be awkward at best, e.g.:

short s
s += (short)1;

Anyway, just another aspect to this whole discussion...

Mike Rosenblum
A: 

The effect you are seeing...

short - short = int

...is discussed extensively in this Stackoverflow question: [link] byte + byte = int… why?

There is a lot of good information and some interesting discussions as to why it is that way.

Here is the "top voted" answer:

I believe it's basically for the sake of performance. (In terms of "why it happens at all" it's because there aren't any operators defined by C# for arithmetic with byte, sbyte, short or ushort, just as others have said. This answer is about why those operators aren't defined.)

Processors have native operations to do arithmetic with 32 bits very quickly. Doing the conversion back from the result to a byte automatically could be done, but would result in performance penalties in the case where you don't actually want that behaviour.

-- Jon Skeets

Enjoy,

Robert C. Cartaino

Robert Cartaino