Is `*((*(&array + 1)) - 1)` safe to use to get the last element of an automatic array? Is `*((*(&array + 1)) - 1)` safe to use to get the last element of an automatic array? arrays arrays

Is `*((*(&array + 1)) - 1)` safe to use to get the last element of an automatic array?


No, it is not.

&array is of type pointer to char[SOME_SIZE] (in the first example given). This means &array + 1 points to memory immediately past the end of array. Dereferencing that (as in (*(&array+1)) gives undefined behaviour.

No need to analyse further. Once there is any part of an expression that gives undefined behaviour, the whole expression does.


I don't think it is safe.

From the standard as @dasblinkenlight quoted in his answer (now removed) there is also something I would like to add:

C99 Section 6.5.6.8 -

[...]
if the expression P points to the last element of an array object, the expression (P)+1 points [...]
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.

So as it says , we should not do this *(&array + 1) as it will go one past the last element of array and so * should not be used.

As also it is well known that dereferencing pointers pointing to an unauthorized memory location leads to undefined behaviour .


I believe it's undefined behavior for the reasons Peter mentions in his answer.

There is a huge debate going on about *(&array + 1). On the one hand, dereferencing &array + 1 seems to be legal because it's only changing the type from T (*)[] back to T [], but on the other hand, it's still a pointer to uninitialized, unused and unallocated memory.

My answer relies on the following:

C99 6.5.6.7 (Semantics of additive operators)

For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

Since &array is not a pointer to an object that is an element of an array, then according to this, it means that the code is equivalent to:

char array_equiv[1][SOME_SIZE] = { ... };/* ... */printf("Last element = %c", *((*(&array_equiv[0] + 1)) - 1));

That is, &array is a pointer to an array of 10 chars, so it behaves the same as a pointer to the first element of an array of length 1 where each element is an array of 10 chars.

Now, that together with the clause that follows (already mentioned in other answers; this exact excerpt is blatantly stolen from ameyCU's answer):

C99 Section 6.5.6.8 -

[...]
if the expression P points to the last element of an array object, the expression (P)+1 points [...]
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.

Makes it pretty clear that it is UB: it's equivalent to dereferencing a pointer that points one past the last element of array_equiv.

Yes, in real world, it probably works, as in reality the original code doesn't really dereference a memory location, it's mostly a type conversion from T (*)[] to T [], but I'm pretty sure that from a strict standard-compliance point of view, it is undefined behavior.