6

Suppose I have some pointer, which I want to reinterpret as static dimension array reference:

double *p;
double (&r)[4] = ?(p); // some construct?

// clarify
template< size_t N> void function(double (&a)[N]);
...
 double *p;
function(p); // this will not work.
//  I would like to cast p as to make it appear as  double[N]

Is it possible to do so? how do I do it?

Anycorn
  • 50,217
  • 42
  • 167
  • 261

3 Answers3

12

It's ugly:

double arr[4];
double* d = arr;

double (&a)[4] = *static_cast<double(*)[4]>(static_cast<void*>(d));

Be sure the array type matches what the pointer originally came from.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • `double(*)[4]`, what is this construct? this is the first time I see it – Anycorn Apr 14 '10 at 05:03
  • 1
    one last question, why cast to void* first? – Anycorn Apr 14 '10 at 05:08
  • @aaa: We could do: `reinterpret_cast(d)`, but this relies on implementation defined behavior. C++ standard guarantees that a cast from `void*` to `T*` will always work as long as the `void*` originally pointed at that `T`. The code above is well-formed, because `d`, when casted to `void*`, does indeed point to the original type we are casting to. (This is also why I warn the cast matches exactly what the pointer points at. If we were to cast to anything else, we'd have undefined behavior.) – GManNickG Apr 14 '10 at 05:11
  • 1
    what if d was `new double[]` originally, rather than pointer to double[4]? would `a` still be valid (in first four elements)? I was not quite clear if by type T you meant double or `double[4]`. thank you – Anycorn Apr 14 '10 at 05:18
  • By `T` I meant `double[4]`. I *think* that should work because `double` is a POD type. Hopefully someone else can chime in to confirm. – GManNickG Apr 14 '10 at 05:24
  • 1
    I was always of the impression that `reinterpret_cast(p)` would be the same as `*reinterpret_cast(p)`, but I wanted to comment that since reinterpret_cast is implementation defined this isn't always true. This is a good example because compiling on my system with GCC 4.7, the cast to reference is giving an address 8 bytes offset from the dereferenced cast to pointer. The cast to pointer, cast to type, dereference route is more verbose but definitely safer. – monkey0506 Jan 26 '13 at 00:22
  • @GManNickG, This is **not** OK. The second line `double* d = arr;` is array to pointer implicit conversion the result of which is "a pointer to the first element of the array." See [conv.array]. But `double*` and `double (*) [4]` are different pointer types, and these pointer types are not _pointer-interconvertable_ see [basic.compound] [C++17 6.9.2.4] Therefore what you have is the equivalent of a `reinterpret_cast(d)` and this violates the _strict aliasing rule_. – ThomasMcLeod Oct 28 '18 at 02:28
-3
double *array;
...
...
int sizearray = sizeof(array)/sizeof(double);
Luiguis
  • 404
  • 1
  • 5
  • 11
  • The logic here is wrong. `array` carries no information about what it points to. This will always return the same answer, no matter what. – GManNickG Apr 14 '10 at 05:06
  • 2
    sizeof(array) when array is a pointer will give back the pointer size, usually 4 or more depending on OS. – AndersK Apr 14 '10 at 05:57
-4

Yes, it's called a vector :)

std::vector<double> myVariableArray(4)

EDIT: Rereading, it looks like you want to get the size an array was declared with. You can't do that -- that's a template method feature you can use on occasion. Since a double * doesn't even need to point to doubles there's little way a compiler could give you a sensible answer in any case.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • @GMan: Yeah -- just realized that. Edited. Initially interpreted that as "Can I create an array with a dimension known at runtime" – Billy ONeal Apr 14 '10 at 04:54