Reputation: 275
Is subtraction of pointers not pointing to different elements of same array valid in C?
Is something such as below guaranteed to work according to C Standards? I vaguely remember reading that this is not valid?
int * a;
int * b;
a = (int*) 100;
b = (int*) 200;
printf("%d\n", b-a);
Will this give me 25.
Upvotes: 3
Views: 587
Reputation: 119877
Of course it's undefined. Subtracting two arbitrary pointers (viewed as integers) is not even guaranteed to be a multiple of your object's size.
Upvotes: 0
Reputation: 8180
Even the standard does not promise a defined behavior, the result is correct. An integer needs in your architecture 4 bytes. Thus, the difference give you the number of integer values the both pointer are apart. You can use the difference as an index or offset in an array. For the same reason
int *p = (int*) 100;
p++;
will result in p=104.
Upvotes: 0
Reputation: 224944
From the C spec, Appendix J.2 Undefined behaviour:
Pointers that do not point into, or just beyond, the same array object are subtracted (6.5.6).
6.5.6 Additive operators, paragraph 9 says:
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.
There you have it - your example causes undefined behaviour. That said, on most systems it will work just fine. You probably do want to change your printf
format to %td
to indicate that you're printing a ptrdiff_t
type.
Upvotes: 6
Reputation: 258618
This is undefined behavior.
For one, those pointers don't point to memory that you own.
You can only substract pointers that point inside the same array (or one position after the end of the array).
Of course, it will most likely work on most compilers, and you get 25
because sizeof(int) == 4
on your platform. If they were char *
, you'd get 100. (possibly, or it could crash, that's the beauty of UB).
Upvotes: 4