4

I was reading this post and I was wondering, if the CLR converts bytes and Int16 to Int32 for arithmetics, does it convert all Byte, Int16 and Int32 to Int64 when running in 64-bit mode?

Edit: Since the following loop :

for (short i = 0; i < 10; i++) {
    // ...
}

will produce something like this in IL :

Int16 i = 0;
LOOP:
    Int32 temp0 = Convert_I16_To_I32(i); // !!!
    if (temp0 >= 10) goto END;
    ...
    Int32 temp1 = Convert_I16_To_I32(i); // !!!
    Int32 temp2 = temp1 + 1;
    i = Convert_I32_To_I16(temp2); // !!!
    goto LOOP;
END:

Will the following loop :

for (int i = 0; i < 10; i++) {
    // ...
}

Produce something like this on 64-bit architectures?

Int32 i = 0;
LOOP:
    Int64 temp0 = Convert_I32_To_I64(i); // !!!
    if (temp0 >= 10) goto END;
    ...
    Int64 temp1 = Convert_I32_To_I64(i); // !!!
    Int64 temp2 = temp1 + 1;
    i = Convert_I64_To_I32(temp2); // !!!
    goto LOOP;
END:
Community
  • 1
  • 1
Jazzwave06
  • 1,883
  • 1
  • 11
  • 19
  • Related if not duplicate: [Is an int a 64-bit integer in 64-bit C#?](http://stackoverflow.com/questions/164643/is-an-int-a-64-bit-integer-in-64-bit-c) – Habib Nov 25 '14 at 16:19
  • 1
    Same strategy as many native C and C++ compilers that generate 64-bit code, an *int* is still 32 bits. Just as fast on the processor's execution core, promoting it doesn't buy you a bigger range or more speed. The CLI was originally targeted to RISC processors that don't support fractional word size operations, still popular back in the late 1990s. – Hans Passant Nov 25 '14 at 16:19

1 Answers1

3

Actually, CLR doesn't do anything: C# compiler does. You see, CLR does support Byte and Int16 types, however it does not support arithmetic operations on them, so to perform arithmetic operations on Byte and Int16, they initially should be transformed to smallest supported type (Int32).

Behavior of this transformation is dependent on language. C# team choosed to automatically convert all computations on these type to Int32, so you see corresponding IL. VB.NET choosed to save type information, so no type conversion is seen in code, however IL code in this case is more cumbersome: they have to use conversion to Int32, check if overflow has happened and then convert back from Int32.

So, it is dependent on language. C# specifications clearly state that arithmetic operations are size-independent, so on every platform you will see conversion to Int32. CLR does specify that Int32 type is always take 4 bytes of memory space, but it's not limited by this: CLR also supports native int type, which size is dependent on platform. C# does not allow that, so you can use this type only in unsafe sections.

P.S. Signed/unsigned variancy is omitted for clarity

P.P.S. IntPtr is safe, but it's implementation depend on platform: IntPtr.Size is 4 bytes on 32bit and 8 bytes on 64bit

Aloraman
  • 1,389
  • 1
  • 21
  • 32
  • Yeah I used the term CLR to represent the group of tools responsible for .NET execution. Of course, the CLR is not responsible of producing the IL. Int32 is the smalled supported type, but is it Int64 when the 64-bit flag is on? – Jazzwave06 Nov 25 '14 at 18:10
  • To make long story short: C# automatically converts to smallest supported type **independent** of target platform, so it is always `Int32`, because platform independence is key feature of C# – Aloraman Nov 25 '14 at 18:31