This line is of most importance:
size = *(&a + 1) - a;
As you can see, it first takes the address of a
and adds one to it. Then, it dereferences that pointer and subtracts the original value of a
from it.
Pointer arithmetic in C causes this to return the number of elements in the array, or 5
. Adding one and &a
is a pointer to the next array of 5 int
s after a
. After that, this code dereferences the resulting pointer and subtracts a
(an array type that has decayed to a pointer) from that, giving the number of elements in the array.
Details on how pointer arithmetic works:
Say you have a pointer xyz
that points to an int
type and contains the value (int *)160
. When you subtract any number from xyz
, C specifies that the actual amount subtracted from xyz
is that number times the size of the type that it points to. For example, if you subtracted 5
from xyz
, the value of xyz
resulting would be xyz - (sizeof(*xyz) * 5)
if pointer arithmetic didn't apply.
As a
is an array of 5
int
types, the resulting value will be 5. However, this will not work with a pointer, only with an array. If you try this with a pointer, the result will always be 1
.
Here's a little example that shows the addresses and how this is undefined. The the left-hand side shows the addresses:
a + 0 | [a[0]] | &a points to this
a + 1 | [a[1]]
a + 2 | [a[2]]
a + 3 | [a[3]]
a + 4 | [a[4]] | end of array
a + 5 | [a[5]] | &a+1 points to this; accessing past array when dereferenced
This means that the code is subtracting a
from &a[5]
(or a+5
), giving 5
.
Note that this is undefined behavior, and should not be used under any circumstances. Do not expect the behavior of this to be consistent across all platforms, and do not use it in production programs.