3

I want to do something like:

const int N = 10;
void foo (const int count)
{
  int (* pA) [N][count] = reinterpret_cast<int(*)[N][count]>(new int[N * count]);
  ...
}

But my compiler (VS2010) doesn't want to do it:

error C2057: expected constant expression
error C2540: non-constant expression as array bound

Such a way he expresses his dissatisfaction with the count.

I know, how it can be worked around by implementing a slightly different way. But I just don't get, why does C++ forbid me to use this way. I understand, why C++ needs to know on-stack arrays size at compile time (to allocate array memory). But why the same restrictions are necessary with respect to pointers to array (after all, pointer is just a tool to work with that allocated memory)?

user1234567
  • 3,991
  • 3
  • 19
  • 25
  • `const` is wildly insufficient for guaranteeing compile-time knowability (and, therefore, use as an array bound). – Lightness Races in Orbit Dec 14 '14 at 19:03
  • @Lightness Races in Orbit, but I don't use count as an array bound. I mean, as a bound of a real array. I try to use it as a bound of array, which is only virtual mask for a pointer to work with already allocated memory. That's why it seems to me, this restriction is undue. I realize that I am mistaken, but I don't understand, where? – user1234567 Dec 16 '14 at 19:59
  • 1
    That you're not using `count` to bound the actual data is not enough. Even just trying to use it _as part of a type_ (as you are doing here) is already impossible. Types are a compile-time construct, yet the expression `count` is meaningless until run-time. So how is that supposed to work? – Lightness Races in Orbit Dec 16 '14 at 20:28

1 Answers1

2

Well, actually what you want is in principle alright, but you're using the wrong syntax.

All dimensions except the first have to be compile-time constants, because they're used in pointer arithmetic. The first one can be runtime varying. This works:

int (* pA)[N] = new int[count][N];

Remember that an array is compatible with pointer-to-element-type, and subscripting works exactly the same on both. So when you have a 2-D array allocated (array of arrays), you should store a pointer-to-1D-array.

There's no way to do int[N][count], though, because that would need an array of elements (subarrays) of variable size.

Furthermore, note that N is a constant-expression, but count is not. Even though they both have the same type, count is a parameter, determined at runtime.

If you want to accept a constant integral expression as an argument, make it a template argument:

template <int count>
void foo()

Now count is a constant expression just like N.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720