Formally and pedantically, the 1[&array]
approach is invalid. It causes undefined behavior.
The expression is equivalent to
(implicit array-to-pointer conversion) *(&array + 1)
This expression contains an application of unary *
operator to a pointer that points to an "imaginary" past-the-end object of type int [12]
. This application of *
is formally evaluated and, per 6.5.6/8, produces undefined behavior
If the result points one past the last element of the array object, it
shall not be used as the operand of a unary *
operator that is evaluated.
On the other hand, the situation is very similar to the issue that we had in C89/90, where a + 12
was a valid way to form the past-the-end pointer, while at the same time &a[12]
was considered undefined. &a[12]
is equivalent to &*(a + 12)
, which also applies *
to a past-the-end pointer and thus causes undefined behavior.
C99 legalized the &a[12]
method by stating in 6.5.3.2/3 that &*
combination should essentially "disappear" from the expression, meaning that *
is not evaluated and undefined behavior is not triggered
Similarly, if the operand is the result of a []
operator, neither the &
operator nor the unary *
that is implied by the []
is evaluated and the result is as if the &
operator were removed and the []
operator were changed to a +
operator.
Our situation
(implicit array-to-pointer conversion) *(&array + 1)
is rather similar in essense. It would make sense if the language standard said that in the above context the array-to-pointer conversion and the unary *
operator should "partially annihilate" each other, leaving behind just a simple implicit (int *)
cast. But alas there's nothing like that in the language specification.