You own the memory pointed to by pt
. So you can dereference using *pt
. This is equivalent to *(pt + 0)
or pt[0]
.
It turns out that you can reference both pt[0]
and pt[-1]
since pointer arithmetic is well-defined on your underlying foo
array.
But you don't own the memory at pt[a - b]
since a - b
is not -1 but rather a very large positive number as a
and b
are unsigned types so the result will be an unsigned type too.
Hence you get undefined behaviour.
Undefined behaviour is exactly that: you can expect anything to happen.