https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93848

--- Comment #8 from Martin Sebor <msebor at gcc dot gnu.org> ---
In

  int i[4];
  int (*p)[4] = &i;
  bar_aux (p[1]);

p[0] points to i and p[1] to (char*)&i + sizeof (i) (which is the same as
&i[4]).  The latter is a pointer just past the end of i.  Evaluating
past-the-end pointers is well-defined, as is all pointer arithmetic on them,
just as long as the result is also a valid pointer to the same object (or just
past its end).  The only way past-the-end pointers differ from others is that
the former cannot be dereferenced (by any means, either the * operator, or []
or ->).

In
    int a[1][4];
    printf("%p\n", (void *)&a[1][1]);

on the other hand, the reference to a[1][1] is undefined because a[1] is not a
reference to an element in a but rather just past the end of a, and so it can
be neither dereferenced nor used to obtain pointers other than to a or just
past it.  &a[1] alone is valid (it's equivalent to (char*)&a + sizeof a) and
points just past the end of a, but &a[1][1] is equivalent to (char*)&a + sizeof
a + 1 which is not valid.

Reply via email to