.NET是否在64位体系结构上将Int32推广到Int64用于算术?

时间:2014-11-25 16:09:23

标签: c# .net clr

我正在读这个post,我想知道,如果CLR将字节和Int16转换为Int32用于算术运算,它是否在64位模式下运行时将所有字节,Int16和Int32转换为Int64?

编辑:由于以下循环:

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

会在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:

以下循环:

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

在64位架构上产生类似的东西吗?

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:

1 个答案:

答案 0 :(得分:3)

实际上,CLR没有做任何事情:C#编译器。你看,CLR确实支持ByteInt16类型,但它不支持对它们进行算术运算,所以要对ByteInt16执行算术运算,它们最初应该被转换为最小支持类型(Int32)。

这种转变的行为取决于语言。 C#团队选择自动将这些类型的所有计算转换为Int32,因此您可以看到相应的IL。 VB.NET选择保存类型信息,因此代码中没有看到类型转换,但是在这种情况下IL代码更麻烦:它们必须使用转换为Int32,检查溢出是否已经发生,然后从Int32

所以,它取决于语言。 C#规范明确规定算术运算与大小无关,因此在每个平台上您都会看到转换为Int32。 CLR确实指定Int32类型总是占用4个字节的内存空间,但它不受此限制:CLR还支持native int类型,其大小取决于平台。 C#不允许这样做,因此您只能在unsafe部分使用此类型。

附:为清楚起见,省略了有符号/无符号的变量

P.P.S. IntPtr是安全的,但它的实现依赖于平台:IntPtr.Size在32位上是4个字节,在64位上是8个字节