9

Consider the following code:

int data[2][2];
int* p(&data[0][0]);
p[3] = 0;

Or equivalently:

int data[2][2];
int (&row0)[2] = data[0];
int* p = &row0[0];
p[3] = 0;

It's not clear to me whether this is undefined behaviour or not. p is a pointer to the first element of an array row0 with 2 elements, therefore p[3] accesses past the end of the array, which is UB according to 7.6.6 [expr.add]:

  • When an expression J that has integral type is added to or subtracted from an expression P of pointer type, the result has the type of P.
    • If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.
    • Otherwise, if P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0 ≤ i + jn and the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0 ≤ i − jn.
    • Otherwise, the behavior is undefined.

I don't see anything in the standard that gives special treatment to multidimensional arrays, so I can only conclude that the above is, in fact, UB.

Am I correct?

What about the case of data being declared as std::array<std::array<int, 2>, 2>? This case seems even more likely to be UB, as structs may have padding.

1

1 Answer 1

8

Yes, you are correct, and there is not much to add to it. There are no mutidimensional arrays in C++ type system, there are only arrays (of arrays of arrays of arrays ad libitum).

Accessing an element beyond array size is undefined behavior.

Sign up to request clarification or add additional context in comments.

5 Comments

I feel it's fair to use the term multidimensional array. int[][] is an array with a rank of two. It's a proper array type, and multidimensional communicates clearly that it has more than one extent. It's a term that's also used in cppreference and used by the standard (at least in the revision I checked and linked here).
@FrançoisAndrieux I have my reasons why I prefer to think of [][] constructs in C++ as arrays of arrays rather than multidimensional arrays (this question is one of them!). Even in your linked quote "multidimensional" seems to be more or less informal, with the formal type below: ... type of the identifier of D is “array of N T.... Multidimenstional arrays just don't exist formally in C++ type system, and I think realizing it eases understanding.
You make it sound like an opinion, but the language specification defines the term. int[2][2] is "an array of 2 array of 2 int", and it's written that "When several “array of” specifications are adjacent, a multidimensional array type is created;". I don't understand what room there is left for interpretation.
@FrançoisAndrieux Because there is no such type. You can call it a multidimensional array, but there is no such type in C++. And standard itself is formally defining the type as an array of N T, as I quoted. And like I already said, this question itself is for me a good reason to call them array of arrays.
@SergeyA If you mean that "multidimensional array" is not a type, I agree that it isn't a type. But it can certainly be used to describes or characterize a type in the sense that you can ask whether or not a type is a multidimensional array. The answer to that question is laid out in the standard. As such it's definitively a valid term to use when discussing c++ and contrary to your answer there are multidimensional arrays because there exists types for which the answer to the question "Is this type a multidimensional array?" is defined by the language to be yes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.