Is array-of-arrays-of-T to pointer-of-T cast a legal operation in C/C++ according to the Standards?
const int *ptr1 = (const int*)arr; // Is it OK/NOK and why?
Yes it is legal. arr
will first decay to a pointer to first element i.e. const int(*)[4]
which is an object pointer. const int *ptr
is also an object pointer type. All object pointer types can be explicitly converted to an object pointer of a different type in C++.
However, although the cast is legal, it would not be legal to indirect through the pointer and attempt to access the pointed object due to "strict aliasing" rule. It should be OK after laundering though:
auto ptr = std::launder(reinterpret_cast<const int*>(arr));
But better to just use:
auto ptr = &arr[0][0]
Which achieves the same. It won't help with accessing elements outside of the first subarray though.
UPD
const int *ptr2 = arr[0]; // Is this the same?
const int *ptr3 = &arr[0][0]; // Same?
Neither of these are casts, both are well-formed and are effectively equivalent.
And here another related question:
int i0 = ptr[0];
int i2 = ptr[2];
int i7 = ptr[7];
This is undefined behaviour even with the laundering. You can only access arr[0]
through the reinterpreted pointer because it is derived from the decayed pointer to first subarray. Accessing ptr[0]
and ptr[1]
would be fine for your ptr2
and ptr3
and my laundered example.