C ++ / CLI二维数组分配失败

时间:2013-05-28 08:56:15

标签: c++-cli

下面的代码打印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;
}

更新: 我已在https://connect.microsoft.com/VisualStudio/feedback/details/788830/c-cli-2-dimensional-array-allocation-with-unsigned-long-long-size-argument-generates-invalid-code

提交了连接错误报告

1 个答案:

答案 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上提交此问题。如果您不想花时间做这件事,请告诉我,我会照顾它。