-1

This is in C. I am learning C and this is an example in a slide from class.

int main(int argc, char *argv[]) {
    int a = 5, b = 10, c;
    int *p = &a, *q = &b;
    c = p - q;
    printf("%d", c);
    return 0;
}

The output when I run it is 3 and I don't understand why. It seems like since it is using & it would subtract to memory addresses and the output would be a memory address to -5.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
Benjamin Dagg
  • 57
  • 5
  • 12

2 Answers2

5

You are subtracting the address of the pointers not what they are pointing to and you'll get whatever the difference is between the two memory addresses is which is not guaranteed to be anything specific. If you run it on a different machine or compiler it will most likely be totally different values as a and b can be assigned a variety of addresses. For example on my machine it is 1. A phenomenons like this are called undefined behavior for a reason as you cannot guarantee the same result across all compilers and machines.

If you instead dereferenced p and q like this c = *p - *q; you would get -5 as c as the difference between the two set vales. Also if you assigned p and q as int *p = a, *q = b; then you would also get c as -5 because then you are literally setting the pointers to different address and trying to access after doing something like that will in all cases be a terrible idea.

Dom
  • 1,687
  • 6
  • 27
  • 37
  • Thanks but I wasn't trying to subtract what they are pointing to this was an example from the teacher and I didn't understand it I just thought in my mind that it would be -5. Can you please explain why it is 3? – Benjamin Dagg Feb 12 '16 at 02:27
  • @BenjaminDagg it's just the difference in the memory address as I explained in the answer. It may be 3 now, but recompile it on a different computer or compiler and it will most likely be very different as the addresses will be different. – Dom Feb 12 '16 at 02:31
  • @BenjaminDagg There's no special reason it's 3. It just happened to be 3. If you flip a coin, it may come up heads, but there's no reason it came up heads. It just did. Why do you expect -5? That's the mistake -- there's no reason you should expect that. – David Schwartz Feb 12 '16 at 02:37
3

Subtracting 2 pointers that are not of the same array is undefined behavior.

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. C11 §6.5.6 9

Instead, to get some numeric difference, convert values to intptr_t.

int main(int argc, char *argv[]) {
  int a = 5, b = 10, c;
  int *p = &a, *q = &b;
  intptr_t ip = (intptr_t) p;
  intptr_t iq = (intptr_t) q;
  intptr_t diff = ip -iq;
  printf("%lld", (long long) diff);
  return 0;
}

Of course the value you print may not be 5. The locations of the int vary from compile to compile.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256