The cast itself is fine. What might indeed be questionable would be using a pointer to an element within one subarray to access elements in a different one: While the operation is clearly well-defined at a lower level (everything's aligned properly, no padding, the types match, ...), my impression of the C standard has been that it is worded in a way that allows bounds-checking implementations to be standards-conforming.
Note, however, that linearly traversing a multi-dimensional array might nevertheless still be permissible as a pointer pointing past a subarray (which normally must not be dereferenced) also happens to be a pointer to the first element of the next subarray. What this thought leads to is pointer arithmetics being non-associative:
It is my understanding that an expression such as (int *)arr + 13
involves undefined behaviour1, but might become well-defined if you split it into two steps ((int *)arr + 10) + 3
.
If you do want to do it in a single step, there's of course also the option of dropping to the byte level, ie (int *)((char *)arr + 13 * sizeof (int))
, which should be unproblematic as in contrast to other pointer types, character pointers are bounded by the outermost enclosing object.
I've had discussions about this before, but I don't remember if there ever was a definitive conclusion resolving this particular ambiguity.
1 C11, section 6.5.6 §8
[...] If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. [...]
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…