下面的代码打印0和3.这是代码生成错误吗? 我在.NET 4.0下运行Visual Studio 2012 Update 3 RC
#include "stdafx.h"
using namespace System;
int main(array<System::String ^> ^args)
{
unsigned long long d1 = 5, d2 = 3;
auto arr = gcnew array<Object^, 2>(d1, d2);
Console::WriteLine(arr->GetLength(0));
Console::WriteLine(arr->GetLength(1));
return 0;
}
提交了连接错误报告
答案 0 :(得分:3)
是的,这绝对像小虫一样嘎嘎作响。编译器为此代码生成错误的IL,对于必须将unsigned long long
转换为int似乎非常困惑。您可以通过运行ildasm.exe来查看错误的IL,相关的代码段是:
IL_000a: ldloc.3
IL_000b: conv.i4
IL_000c: ldloc.2
IL_000d: conv.i4
IL_000e: conv.i8 // <=== here!
IL_000f: newobj instance void object[0...,0...]::.ctor(int32,
int32)
地址IL_000e处的指令是麻烦制造者,将IL_000d产生的int转换回8位整数。然后,这会传递传递给数组构造函数的参数。奇怪的是,IL验证者也没有抓住它。
这不是Update 3的错误,这在VS2008中也以完全相同的方式失败,所以这肯定是一个老问题。它也非常特定于从无符号long long到System :: Int32的强制转换,它不会长时间出错。很可能是因为这个问题长期未被发现。请注意,编译器会发出此代码的警告,抱怨它必须将unsigned long long截断为int。因此,通过编译/ WX开启来捕捉这一不幸事件。
错误和警告的解决方法是自己显式转换变量:
auto arr = gcnew array<Object^, 2>((int)d1, (int)d2);
您可以在connect.microsoft.com上提交此问题。如果您不想花时间做这件事,请告诉我,我会照顾它。