15

Possible Duplicate:
May I treat a 2D array as a contiguous 1D array?

Consider the following code:

int array2d[10][10];
int *array1d = array2d[0];

I never heard of an implementation where it wouldn't work, but is it legal to access and manipulate array2d via array1d? Which section of the standard allows this? Is there anything in the standard preventing implementations from inserting extra space or padding between each of the second level arrays (not that its needed, but still)?

Bonus question: Is there a way to access array2d as an int[100] which does not require a reinterpret_cast or a C-style one?

Community
  • 1
  • 1
K-ballo
  • 80,396
  • 20
  • 159
  • 169

2 Answers2

6

If memory serves, the standard gives this as an example of something that's officially undefined behavior, but essentially always works. [Edit: Here's what I was thinking of: C99, §J.2 (Undefined behavior):

  • An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5])

I'm not entirely certain that applies though, as you're getting the address of the beginning of an array and converting it to a simple pointer to the underlying type.]

Arrays are required to be contiguous, so it cannot insert any padding between elements of an array. That's true whether you have an array of int or an array of arrays.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

This is indeed legal. The Standard clearly states multidimensional arrays to be simply larger 1D arrays. I don't have the exact quote to hand, but I know that it is true.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • I recently dug up the standardese on 2D array layout (answer [here](http://stackoverflow.com/questions/10618473/is-this-c-code-portable-assuming-multidimensional-arrays-have-continuous-mem/10618866#10618866)). I 'm not sure where the part that says an array `T[n]` takes up *exactly* `n * sizeof(T)` is though. – Jon May 25 '12 at 21:39
  • Basically the "contains" in the very first quote makes me slightly nervous. Why not stronger wording? "Contains" just gives a lower bound. – Jon May 25 '12 at 21:41
  • 2
    @Jon C++2003, §5.3.3/2: `sizeof`: When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element. – Robᵩ May 25 '12 at 22:04
  • Having a guarantee that `sizeof(T[n]) == n * sizeof(T)` (which there is) is not enough to guarantee that the behaviour is correct. What about alias analysis? In the OP's code `array1d` is an iterator inside a `int[10]` array -- now suppose there is an `int* p = array2d[1];`. An optimizer (that will keep track of where those pointers were initialized from) is going to be interested as to whether `array1d` and `p` accesses are allowed to alias or not. C++ as a language is not an assembler but also a contract between coder and implementation. – Luc Danton May 28 '12 at 09:51
  • There's no alias violation here. There are `n * m` ints and you can legally point to any of them with an `int*`, and they're guaranteed contiguous so you can increment the pointer to move to the next. – Puppy May 28 '12 at 11:12