In C and C++, it is often useful to use a past-the-end pointer to write functions that can operate on arbitrarily large arrays. C++ gives a std::end overload to make this easier. In C, on the other hand, I've found it's not uncommon to see a macro defined and used like this:
#define ARRAYLEN(array) (sizeof(array)/sizeof(array[0]))
// ...
int a [42];
do_something (a, a + ARRAYLEN (a));
I've also seen a pointer arithmetic trick used to let such functions operate on single objects:
int b;
do_something (&b, &b + 1);
It occured to me that something similar could be done with arrays, since they are considered by C (and, I believe, C++) to be "complete objects." Given an array, we can derive a pointer to an array immediately after it, dereference that pointer, and use array-to-pointer conversion on the resulting reference to an array to get a past-the-end pointer for the original array:
#define END(array) (*(&array + 1))
// ...
int a [42];
do_something (a, END (a));
My question is this: In dereferencing a pointer to a non-existent array object, does this code exhibit undefined behaviour? I'm interested in what the most recent revisions of both C and C++ have to say about this code (not because I intend to use it, as there are better ways of achieving the same result, but because it's an interesting question).