I stumbled upon the behavior that bitwise or arithmetic operations are not allowed on primitive types smaller than 32 bit, but the respective assignment operations are in fact allowed:
short BitwiseAnd(short a, short b) { return a & b; } // error
short BitwiseAndAssignment(ref short a, short b) { a &= b; } // works
short Add(short a, short b) { return a + b; } // error
short AddAssignment(ref short a, short b) { a += b; } // works
The same behavior holds for other short primitive types like byte
, sbyte
, and ushort
.
I understand that arithmetic and logical operations are defined for 32-bit and larger types (int
, long
...) because it's what the processor provides (see this question), and shorter types are widened and can be casted back to 8 or 16 bit. However, is there a reason why this would work in an assignment operator? First I assumed that behind the scenes, the short
s are casted to int
, but then you would have an assignment/return value short value = (some int)
, which should yield an error since the cast is not implicit.
On a different note: I tried out some code in Visual Studio's immediate window, but there, a lot more code seems to work. The immediate window probably does some implicit casting which would usually be explicit. E.g., short a = (int)5;
is allowed in the immediate window. So that's not helping.
However, is there a reason why this would work in an assignment operator?
Yes: because otherwise the assignment operator could never work for these types - there would be no syntax that allowed it to work. The expectation of a += b
or a &= b
is clear, so the conversion is performed automatically.
With a + b
or a & b
, as you already note: this is widened for performance reasons; syntax exists to put it back, specifically (short)(a+b)
etc.