hello all,
I get this doubt about this behavior of C.
consider the following code.
int a,b,d1,d2,diff;
d1= &a;
d2 = &b;
diff = &a-&b;
printf("\nDifference between address: %d", diff);
diff = d1-d2;
printf("\nDifference between address(stored in integers): %d", diff);
ideally, both printf should result same output.
but as expected diff = d1-d2 gives 4.
but diff = &a-&b gives 1.
Why so when C doesn't really support operator overloading.
The short (and technical, and not very helpful) answer is
that the code's behavior is undefined: The C language doesn't
specify what should happen, so *anything* might happen.
A longer answer ...
First, pointer arithmetic always operates in units of the
pointed-at type. Adding 1 to an `int*' advances the pointer
to the next `int', adding 1 to a `double*' advances to the next
`double', and so on. Even if an `int' occupies four bytes and
a `double' occupies eight, adding 1 advances the pointer by the
proper distance for its type.
... so subtraction works the same way: If you start with an
`int*', add 1 to produce another pointer to the next `int', and
then subtract the two values, what do you get? You get 1: the
distance between the two objects is expressed in multiples of
the object size. If you start with a pointer `p' and derive a
new pointer `q' by computing `q = p + 3', it should come as no
surprise that `q - p' yields 3.
However, this adding and subtracting only works when you're
navigating within in an array that contains the pointed-at objects.
That's the only way to be sure of the right adjacency and spacing
that allows pointer arithmetic to be defined. Consider: If you
have two objects that are six bytes long, and if they exist at
addresses eight bytes apart, the distance between them is not a
multiple of the size and pointer arithmetic falls down: You can't
add 1 to a pointer and have it advance by one-and-a-third objects!
... and that's where the undefined behavior enters your code.
Since `a' and `b' are free-standing objects, unrelated to each
other and not part of the same array, subtracting pointers to them
cannot be guaranteed to produce a sensible answer. So C does not
promise that anything sensible will happen; C says "the behavior
is undefined" and just leaves it at that. In your case it seems
that `a' and `b' did in fact wind up in adjacent memory regions,
but that's a coincidence, not something C promises nor that you
can rely on.
Next topic: Why 1 vs. 4?
C promises that a pointer can be converted to some kind of
integer, but says very little about how wide an integer is needed
and says nothing at all about the nature of the conversion. You
take a pointer, convert it to an `int', and you get some kind of
value. (It is not even guaranteed that you'll get the same value
every time!) In your case, it seems that the address part of your
pointer (or part of it) simply got transliterated into a bag of
bits that were then interpreted as an `int' value -- that's a very
common scheme, but not the only one.
But notice what's left behind: The pointer "knew" what kind
of object it pointed to, and hence the size of that object, and
thus knew how to compensate for that size when doing arithmetic.
The `int' resulting from conversion, though, has no information
about the type of object the pointer aimed at, and cannot make
adjustments for object size. So when you subtract the integers
there's no adjustment: You get the distance between the objects
expressed not in object-units, but in bytes (again, this is a
common outcome but not the only possibility).
Pointers are not "just addresses," but "addresses with type."