Question

I have had a piece of code that was similar to the following:

  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);

The length of the 2D array was variable and the length information was stored in 2 double variables. It turned out not to work:

  iTest1 = 1077149696
  iTest2 = 0

What is going wrong here? Is the compiler or interpreter not able to use double variables for array length?

Actually it works when I have a 1D array:

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


The solution for the problem above is an explicit cast to int, which should be done anyway, but can also be forgotten (if you don't give a damn on compiler warnings):

  array<int^,2>^ arr2Test = gcnew array<int^,2>((int)dTest1, (int)dTest2);
Was it helpful?

Solution

First, as Hans said, int^ is non-standard, you always want int. Once re-written to gcnew array<int,2>(dTest1, dTest2), I still got the same results as you did.

I took the code, and decompiled it to C# syntax with .Net Reflector:

int[,] numArray = null;
double num5 = 15.0;
double num4 = 20.0;
numArray = new int[(int) num5, (double) ((int) num4)];

And here's the actual IL for that last line:

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)

So it looks like it's putting a double on the evaluation stack, where it should be an integer.

20.0, as a double, is these bytes: 0x4034000000000000. The value you got for iTest1 is 1077149696, which is 0x40340000.

The array constructor took the double that was on the stack, and interpreted the bytes as two integers, and constructed the array as it was told.

As you can see, it converts the first parameter (num5, 15.0) to an integer properly. That's why the one-dimensional array works.

This strikes me as possibly a bug in the C++/CLI compiler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top