Let me give a special opinion: this (at least in C ++) is undefined behavior for the same reason as in another question related to this question.
Let me first clarify an example with some typedefs that will simplify the discussion.
typedef int two_ints[2]; typedef int* int_ptr; typedef two_ints* two_ints_ptr; two_ints arr; two_ints_ptr ptr = (two_ints_ptr) &arr[1]; int_ptr temp = ptr[0];
So, the question is whether there is an object of type two_ints whose address matches the address arr[1] (in the same sense that the address arr matches the address arr[0] ) and therefore there is no object to which ptr[0] , however, you can convert the value of this expression to one of the int_ptr types (here with the name temp ), which points to an object (namely, an integer object is also called arr[1] ).
The point at which I think the undefined behavior is in the ptr[0] rating, which is equivalent (in 5.2.1 [expr.sub]) to *(ptr+0) ; more precisely, the ptr+0 score has undefined behavior.
I will give my copy of C ++, which is not official [N3337], but probably the language has not changed; I am a little worried that the section number does not at all coincide with the number indicated in the accepted answer of the related question. Anyway, for me it's §5.7 [expr.add]
If both pointer operands and the result point to elements of the same array object or one after the last element of the array object, the evaluation should not lead to overflow; otherwise, the behavior is undefined.
Since the ptr pointer operand has a pointer to two_ints , the "array object" mentioned in the quoted text should be an array of two_ints objects. However, there is only one such object: a dummy array, whose unique element is arr , which we must call in such situations (such as: "a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one ...") but it is clear that ptr does not indicate its unique element arr . Thus, although ptr and ptr+0 , without a doubt, equal values, none of them even points to elements of any array object (not even fictitious), not a single end to the end of such an array object, and the condition of the specified phrase is not fulfilled. The consequence is (not that overflow occurs, but) that the behavior is undefined.
So, the behavior is already undefined before applying the indirectness operator * . I would not argue about the behavior of undefined from the last assessment, although the phrase "the result is an lvalue referring to the object or function to which the point of expression refers" is difficult to interpret for expressions that do not apply to any object in everything. But I would be gentle in interpreting this, since I believe that dereferencing a pointer past an array should not be undefined behavior (for example, if it is used to initialize a link).
This assumes that if you write (*ptr)[0] or **ptr instead of ptr[0][0] , then the behavior will not be undefined. This is curious, but this is not the first time that the C ++ standard surprises me.