2013-05-28 81 views
3

下面的代碼打印0和3.這是代碼生成錯誤嗎? 我在.NET 4.0和Visual Studio 2012更新3 RCC++/CLI 2維陣列分配失敗

#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

回答

3

是提起連接錯誤報告,那肯定叫聲也像一個bug。編譯器爲這段代碼生成壞的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產生回8位整數的INT。然後,它會傳遞給數組構造函數的參數。奇怪的是,伊利諾伊州的驗證者也沒有發現。

這不是一個更新3的錯誤,這在VS2008中也會以完全相同的方式失敗,所以這肯定是一個老問題。對於從unsigned long long到System :: Int32的強制轉換,它也非常具體,它很長一段時間不會出錯。這個可能的原因已經沒有被發現這麼久了。請注意,編譯器對此代碼發出警告,抱怨它必須將無符號long long截斷爲int。所以通過編譯/ WX打開來抓住這個不幸事件。

兩個錯誤和警告的解決方法是顯式轉換變量自己:

auto arr = gcnew array<Object^, 2>((int)d1, (int)d2); 

您可以在connect.microsoft.com提出這個問題。如果你不想花時間做這件事,並且我會照顧它,請告訴我。

+0

感謝Hans,我會在連線上提交。 –

+0

@ K.M。當你這樣做時,考慮在這裏添加一個鏈接。這樣,遇到這個問題的人也可以訪問和投票錯誤報告。 –

+0

只是fyi,IL驗證器沒有捕獲它,因爲它是(部分)禁用的,因爲C++/CLI生成不可驗證的代碼(除非用/ clr:safe構建)。一旦解除對可驗證代碼的限制,它通常無法知道堆棧在通話時是否有意義。 – poizan42