使用双变量定义2D CLI数组长度失败

时间:2013-07-02 15:38:21

标签: arrays c++-cli variable-declaration

我有一段与以下内容类似的代码:

  double dTest1, dTest2;
  int iTest1, iTest2;
  dTest1 = 15.0;
  dTest2 = 20.0;
  array<int^,2>^ arr2Test = gcnew array<int^,2>(dTest1, dTest2);
  iTest1 = arr2Test->GetLength(0);
  iTest2 = arr2Test->GetLength(1);

2D数组的长度是可变的,长度信息存储在2个双变量中。事实证明这不起作用:

  iTest1 = 1077149696
  iTest2 = 0

这里出了什么问题?编译器或解释器是否无法将双变量用于数组长度?

实际上,当我有一维数组时它会起作用:

  array<int^>^ arrTest = gcnew array<int^>(dTest1);
  iTest1 = arrTest->GetLength(0);
  --> iTest1 = 15


上面问题的解决方案是对int的显式强制转换,无论如何都应该这样做,但也可以忘记(如果你不对编译器警告发出诅咒):

  array<int^,2>^ arr2Test = gcnew array<int^,2>((int)dTest1, (int)dTest2);

1 个答案:

答案 0 :(得分:2)

首先,正如汉斯所说,int^是非标准的,你总是想要int。重新写入gcnew array<int,2>(dTest1, dTest2)后,我仍然会得到与您相同的结果。

我接受了代码,并使用.Net Reflector:

将其反编译为C#语法
int[,] numArray = null;
double num5 = 15.0;
double num4 = 20.0;
numArray = new int[(int) num5, (double) ((int) num4)];

这是最后一行的实际IL:

L_001a: ldloc.s num5 // Loads the local variable onto the evaluation stack.
L_001c: conv.i4 // Converts the value at the top of the evaluation stack to int32
L_001d: ldloc.s num4 // Loads the local variable onto the evaluation stack.
L_001f: conv.i4 // Converts the value at the top of the evaluation stack to int32
L_0020: conv.r8 // Converts the value at the top of the evaluation stack to float64
L_0021: newobj instance void int32[0...,0...]::.ctor(int32, int32)

所以看起来它在评估堆栈上放了两倍,它应该是一个整数。

作为double的

20.0是这些字节:0x4034000000000000。您获得的iTest1的值为1077149696,即0x40340000

数组构造函数接受堆栈上的double,并将字节解释为两个整数,并按照告诉的方式构造数组。

如您所见,它将第一个参数(num5,15.0)正确转换为整数。这就是一维数组工作的原因。

这让我觉得可能是C ++ / CLI编译器中的一个错误。