Search code examples
c++clangreinterpret-cast

reinterpret_cast to a variable-sized array


So it seems like I can use reinterpret_cast to tell my compiler (Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)) to treat a pointer as an array of arrays:

void f(int *p, size_t n, size_t m) {
  auto a = reinterpret_cast<int(&)[n][m]>(p);

  //...
}

But if I give the array reference an explicit type (to make sure I'm getting what I want), I get an error:

void g(int *p, size_t n, size_t m) {
  int (&a)[n][m] = reinterpret_cast<int(&)[n][m]>(p);
  // error: non-const lvalue reference to type 'int [n][m]' 
  //        cannot bind to a value of unrelated type 'int [n][m]'

  //...
}

That's a pretty confusing error message, so I used decltype to get the compiler to tell me what it thought the type was:

template<class Type> struct S;
void h(int * p, size_t n, size_t m) {
  auto a = reinterpret_cast<int (&)[n][m]>(p);
  S<decltype(a)>(); 
  // error: implicit instantiation of undefined template 'S<int (*)[m]>'

  //...
}

But that using type didn't work either:

void i(int * p, size_t n, size_t m) {
  int (*a)[m] = reinterpret_cast<int (&)[n][m]>(p);
  // error: cannot initialize a variable of type 'int (*)[m]' with an lvalue
  // of type 'int [n][m]'

  //...
}

Since the compiler is perfectly happy with the explicit types if n and m are known at compile-time, I'm guessing that has something to do with it.

Is there any valid explicit type I can give a?


Solution

  • From this answer, it looks like one solution is to use a local typedef or using:

    void i(int * p, const size_t n, const size_t m) {
      using n_by_m = int[n][m];
      n_by_m &a = reinterpret_cast<n_by_m&>(p);
    
      // ...
    }