What goes on at a low level when I do this?
Int32 a = 0;
Int16 b = 50;
a = b;
What goes on at a low level when I do this?
Int32 a = 0;
Int16 b = 50;
a = b;
Something like this:
IL_0001: /* 1F | 32 */ ldc.i4.s 50
IL_0003: /* 0B | */ stloc.1
IL_0004: /* 07 | */ ldloc.1
IL_0005: /* 0A | */ stloc.0
At a lower level, it depends on the machine architecture and optimization level. Code like this specifically, that has no effect, will probably just be omitted altogether. Otherwise, it'll be simple code, perhaps like this:
movsx eax, word ptr [ebp+12]
mov [ebp+8], eax
movsx
is the x86 instruction which preserves the sign of a shorter number when it's being loaded into a larger destination; basically, it looks at the most significant bit of the smaller source and copies it into the remaining bits when it's extending the number.
From Reflector:
.method public hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] int32 num,
[1] int16 num2)
L_0000: nop
L_0001: ldc.i4.0 ; Load the constant 0
L_0002: stloc.0 ; Store the value into local var 0
L_0003: ldc.i4.s 50 ; Load the constant 50 - notice it treats it as a 32-bit value
L_0005: stloc.1 ; Store the value into local var 1
L_0006: ldloc.1 ; Load local var 1
L_0007: stloc.0 ; Store the value into local var 0
L_0008: ret
}
At the IL level, nothing special happens in the assignment, but notice that ldc.i4.s 50
treats the literal value as a 4-byte (32-bit) integer.
When the code is JIT compiled, the resulting assembly code probably just promotes the value 50 to a 32-bit wide value.
The evaluation stack doesn't have a representation smaller than 32-bits. [Edit, in most cases (thanks for the update from the comment :)] Until you actually store a 16-bit value somewhere other than the stack, nothing special happens because the short
and int
are the same size. Here are the only operations where you would see a difference:
b = (short)a
conv.i4
instruction mentioned in the comment.*(short*)c = b
or assignment to a struct member where the struct is marked StructLayout.Explicit
or has a packing less than 4.checked { b = (short)a; }
(a < -32768 || a > 32767)
.