First, the traditional way to get the size of an array is sizeof a/sizeof *a
. C++11 adds std::extent<decltype(a)>::value
. There is of course no way to get an array’s size from just a pointer to it, as in
void f(int x[]) {/* no size here */}
Since an array is not a suitable operand to -
, the array-to-pointer conversion occurs for the right-hand operand, producing an int*
. Both operands must be of this type for the subtraction to result in a number of int
s. &arr
is of course a pointer to the array (of type int(*)[5]
, which conveys the size), and so therefore is &arr+1
. Adding a *
(or, equivalently, writing (&arr)[1]
) produces an lvalue that supposedly refers to “the next array after arr
”, which itself decays to a pointer that works with -
.
However, as the indexing form indicates, this involves referring to an array that does not exist and is thus undefined behavior.