This is a mine field, but I’ll give it a try:
&arr
returns a pointer to anint[5]
+ 1
steps the pointer oneint[5]
*(&arr + 1)
dereferences the result back to anint(&)[5]
I don’t know if this causes undefined behavior, but if it doesn’t, the next step will be:*(&arr + 1) - arr
does pointer arithmetics after the twoint[5]
‘s have decayed toint
pointers, returning the diff between the twoint
pointers, which is5
.
Rewritten to make it a bit clearer:
int arr[5] = {5, 8, 1, 3, 6};
int (*begin_ptr)[5] = &arr + 0; // begin_ptr is a int(*)[5]
int (*end_ptr)[5] = &arr + 1; // end_ptr is a int(*)[5]
// Note:
// begin_ptr + 1 == end_ptr
// end_ptr - begin_ptr == 1
int (&begin_ref)[5] = *begin_ptr; // begin_ref is a int(&)[5]
int (&end_ref)[5] = *end_ptr; // end_ref is a int(&)[5] UB here?
auto len = end_ref - begin_ref; // the array references decay into int*
std::cout << "The length of the array is: " << len << '\n'; // 5
I’ll leave the question if it’s UB or not open but referencing an object before the referenced storage has been allocated does look a bit suspicious.