0

I've got a 4x4 matrix and do stuff on it. After some tests, I was under the impression that the first coordinate is automatically incremented/decremented depending on the second's value, even though that seemed impossible. In order to make it clear, I ran the most basic test: printing.

To my surprise, it turns out that the (first) coordinate is kinda sorta automatically adjusted depending on the second's value, that is, the following code prints in one line all the matrix's elements with no segfault whatsoever:

for (int j = 0; j < 16; j++)
    printf("%d ", mx[0][j])

The first thing my mind went off to was a potential optimization the compiler does, but the result was the same with the most basic settings.

Please explain what's going on.

WIlopu
  • 47
  • 7
  • Just because it works on your particular system, when compiled with your particular compiler, using your particular compiler flags, does not mean it works in general. You're actually invoking undefined behavior. – Tim Čas Feb 18 '15 at 23:26
  • @Tim: The thing is, it prints the exact values no matter what they are and how I change them. I noticed this because it actually literally breaks my algorithm, which is otherwise correct. In fact, I check whether my index is still within the range, but since it gets reinitialized to within the range the moment it gets out of it, there's no stopping it 'til the end. ryyker: I did, and the result is the same. – WIlopu Feb 18 '15 at 23:28
  • 2
    This could be useful for your question: http://stackoverflow.com/questions/6290956/one-dimensional-access-to-a-multidimensional-array-well-defined-c. I'm not sure which guarantees about memory storage of multidimensional arrays hold under C standard but you can take a look for yourself. In anycase it's not a matter of "coordinate adjusting", fact is that the array is stored in contiguous memory and since compiler doesn't check for bounds what happens is that `&mx[0][4] == &mx[1][0]` and so on. – Jack Feb 18 '15 at 23:29
  • @Jack: Could this be potentially exploited or is it completely unsafe to exploit it? – WIlopu Feb 18 '15 at 23:34
  • See also https://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array – augurar Feb 18 '15 at 23:43
  • I hear (relatively) recent changes in GCC that require stricter aliasing break this treatment of 2D arrays though; which was a point of contention at one point between GCC devs (claiming that it was UB anyways, and they were right) and C devs (claiming strict aliasing requirements like that have no place in a language like C, and they may have *also* been right). Of course, the breaking isn't certain, and it might "randomly" pop up, depending on whether the compiler decides to use a specific optimization. – Tim Čas Feb 19 '15 at 00:22

1 Answers1

1

In reality the C multi-dimensional arrays defined on declaration (and not product of dynamic memory allocation) are constituted by sequential rows in memory. So,

mx[0]

is the base address of mx array (same as mx alone). The formula to access memory position is

row_index * nr_columns + column_index

(you can easily understand why both ways to access this array are the same).

As it was said, although what you are doing is undefined behaviour, the compiler simply doesn't care and let you break things if you want.

Diogo Pinto
  • 154
  • 7
  • See my 2nd comment on the question itself (the "I hear (relatively) recent changes in GCC" one) as to why the compiler *might* care nevertheless. – Tim Čas Feb 19 '15 at 00:24