When I executed the code of this question, I got this warning:
warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
printf("P-Q: %d, P: %d, Q: %d", (p - q), p, q);
             ~^                 ~~~~~~~
             %ld
As a reflex fix, I used %ld to print the subtraction of two pointers. And the compiler agreed.
Fortunately, I saw a comment from another user mentioning that %td should be used, since the result type of the subtraction is ptrdiff_t. This answer confirms this claim.
Now from GCC's header file of stddef.h, I can see that these types are equivalent in this case:
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#define __PTRDIFF_TYPE__ long int
However, I was just going to suggest a wrong (more or less) fix to the OP, with %ld, instead of %td.
Is there a way I could have understood that the compiler warning alone was not enough? Or maybe to wisely have interpreted the warning itself, and not just react.
 
    