#include
int main() {
int *p = 100;
int *q = 92;
printf(\"%d\\n\", p - q); //prints 2
}
Shouldn\'t the output of above pr
Undefined behavior aside, this is the behavior that you get with pointer arithmetic: when it is legal to subtract pointers, their difference represents the number of data items between the pointers. In case of int
which on your system uses four bytes per int
, the difference between pointers that are eight-bytes apart is (8 / 4)
, which works out to 2
.
Here is a version that has no undefined behavior:
int data[10];
int *p = &data[2];
int *q = &data[0];
// The difference between two pointers computed as pointer difference
ptrdiff_t pdiff = p - q;
intptr_t ip = (intptr_t)((void*)p);
intptr_t iq = (intptr_t)((void*)q);
// The difference between two pointers computed as integer difference
int idiff = ip - iq;
printf("%td %d\n", pdiff, idiff);
Demo.
According to the standard (N1570)
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; the result is the difference of the subscripts of the two array elements.
These are integer pointers, sizeof(int)
is 4. Pointer arithmetic is done in units of the size of the thing pointed to. Therefore the "raw" difference in bytes is divided by 4. Also, the result is a ptrdiff_t
so %d
is unlikely to cut it.
But please note, what you are doing is technically undefined behaviour as Sourav points out. It works in the most common environments almost by accident. However, if p and q point into the same array, the behaviour is defined.
int a[100];
int *p = a + 23;
int *q = a + 25;
printf("0x%" PRIXPTR "\n", (uintptr_t)a); // some number
printf("0x%" PRIXPTR "\n", (uintptr_t)p); // some number + 92
printf("0x%" PRIXPTR "\n", (uintptr_t)q); // some number + 100
printf("%ld\n", q - p); // 2
int main() {
int *p = 100;
int *q = 92;
printf("%d\n", p - q); //prints 2
}
It is called pointer arthmetic
what happens there.
The value will be (100-92)/sizeof(int)
. In your case sizeof(int)=4
.
In ISO9899 pointer arithmetic is defined so for subtraction ptr-ptr
. Chapter 6.5.6p9
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; the result is the difference of the subscripts of the two array elements.
Your code is undefined behavior.
You cannot simply subtract two "arbitrary" pointers. Quoting C11
, chapter §6.5.6/P9
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; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is
ptrdiff_t
defined in the<stddef.h>
header. [....]
Also, as mentioned above, if you correctly subtract two pointers, the result would be of type ptrdiff_t
and you should use %td
to print the result.
That being said, the initialization
int *p = 100;
looks quite wrong itself !! To clarify, it does not store a value of 100
to the memory location pointed by (question: where does it point to?) p
. It attempts to sets the pointer variable itself with an integer value of 100
which seems to be a constraint violation in itself.
This
int *p = 100;
int *q = 92;
is already invalid C. In C you cannot initialize pointers with arbitrary integer values. There's no implicit integer-to-pointer conversion in the language, aside from conversion from null-pointer constant 0
. If you need to force a specific integer value into a pointer for some reason, you have to use an explicit cast (e.g. int *p = (int *) 100;
).
Even if your code somehow compiles, its behavior in not defined by C language, which means that there's no "should be" answer here.