I believe this is technically undefined behavior. At least in C++, probably in C as well.
In practice it will almost certainly print 20, as explained by other answers, but it violates C11 6.5.6 Additive operators / 9
(and in C++: [expr.add]/4.2
):
When two pointers are subtracted, both shall point to elements of the same array object,
or one past the last element of the array object ...
Your pointers point to two different arrays: to the first elements of a[6]
and a[5]
respectively.
One could argue that the first element of a[6]
is one past the last element of a[5]
, but at least in C++, it's not the case, even though they have the same value: notoriously, how a pointer was derived does matter (that's why things like std::launder
exist).
A non-UB way of computing the same thing would be:
int z = ((uintptr_t)a[6] - (uintptr_t)a[5]) / sizeof(a[0][0]);
This is technically implementation-defined (because of pointer-to-uintptr_t
conversion), but should have an even smaller chance of breaking.