Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When subtracting two pointers in C

Tags:

c

pointers

I was playing with pointers in order to fully get the concept and then wanted to subtract two pointers expecting the distance between these two addresses or something, but apparently I was wrong, so here is my code.

int x = 5, y = 7;
int *p = &y;
int *q = &x;
printf("p is %d\nq is %d\np - q is %d", p, q, (p - q));

Why does the program output p - q is 1? Thank you.

like image 231
Kamoukou Avatar asked Nov 29 '22 13:11

Kamoukou


2 Answers

It is undefined behavior. According to the standard (N1570):

6.5.6 Additive operators
....
9 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.

Note that when allowed, the result is the subscripts difference. So if pointers point to two sequential elements of the same type, the subtraction gives 1, regardless of the size of the type. (This is perhaps the reason why you get 1 in your concrete case.)

like image 143
AlexD Avatar answered Dec 16 '22 09:12

AlexD


Your particular case is cause for undefined behavior since p and q point to unrelated objects.

You can make sense of p-q only if p and q point to the same array/one past the last element of the same array.

int array[10];
int* p = &array[0];
int* q = &array[5];

ptrdiff_t diff1 = q - p;  // Valid. diff1 is 5
ptrdiff_t diff2 = p - q;  // Valid. diff2 is -5

q - p is 5 in this case since they point to elements of the array that are 5 elements apart.

Put another way, p+5 is equal to q. If you start from p and step over 5 elements of the array, you will point to the same element of the array that q points to.


As an aside, don't use the format specifier %d for printing pointers. Use %p. Use %td for ptrdiff_t.

printf(" p is %p\n q is %p\n p-q is :%td", p, q, p-q);`
//            ^^        ^^

See http://en.cppreference.com/w/c/io/fprintf for the valid format specifiers for the different types.

like image 38
R Sahu Avatar answered Dec 16 '22 10:12

R Sahu