4

I am learning pointer arithmetic, and I came across something like this:

char *str1, *str2;

/* stuff in between */

int f = str2 - str1;

What is str2 - str1 returning? Let's say str1 = "foo" and str2 = "foobar".

PTN
  • 1,658
  • 5
  • 24
  • 54

3 Answers3

14

The result as you've presented the question isn't defined. For pointer differencing to work correctly they must be from the same array sequence (dynamic, automatic, and even automatic VLA makes no difference). or the one-past address past the last element:

§6.5.6 Additive Operators (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. If the result is not representable in an object of that type, the behavior is undefined. In other words, if the expressions P and Q point to, respectively, the i-th and j-th elements of an array object, the expression (P)-(Q) has the value i−j provided the value fits in an object of type ptrdiff_t. Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points to the last element of the same array object, the expression ((Q)+1)-(P) has the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)), and has the value zero if the expression P points one past the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object.106

That said, if you rephrased so as to be compliant with the rules above, something like:

#include <stdio.h>
int main()
{
    const char *p = "Hello World";
    const char *q = p+7;
    printf("%td\n", q-p);
    return 0;
}

Output

7

and the reason is explained from the cited portion of the standard.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
3

Edited

The answer to this question depends on the situation.

1) In your situation, since the pointers aren't pointing at anything, the result will be garbage

2) If the two pointers are pointing at two valid memory locations in the program space, then the result will be the number bytes of memory in between those 2 location. Although that doesn't make any sense, and it is UB according to the C Spec, if the two pointers are not pointing to the same array or string. If the two pointers point at the same array or string then the result would be the number of elements in between two elements in the same array (When the pointers are pointing at those two elements inside that array). Check this SO question for examples and more explanation.

Community
  • 1
  • 1
Haris
  • 12,120
  • 6
  • 43
  • 70
  • 1
    I'd say 2) only stands if both pointers point to the very same "object". – alk Jul 31 '15 at 06:15
  • "the result will be the number bytes of memory in between those 2 location" is a common result, but not defined by the C spec - it is UB. Other results are possible including program fault or a meaningless value in `f`. – chux - Reinstate Monica Aug 01 '15 at 16:36
0

f = memory address in str2 - memory address in str1. "foo" and "foobar" are values to these memory location these pointers point to.

Example:

If str2 = 0x8000000a

and str1 = 0x80000000

str2 - str1 = 0x8000000a - 0x80000000 
str2 - str1 = 0x0a 
Ishmeet
  • 1,540
  • 4
  • 17
  • 34
  • 1
    I'd say this only stands if both pointer point to the very same "object". – alk Jul 31 '15 at 06:14
  • not necessarily, for example: `char * str2 = &a`, `char * str1 = &b` then the address is on stack and my above answer will have different and non consecutive memory locations. – Ishmeet Jul 31 '15 at 06:30
  • Please see *WhozCraig*'s answer: http://stackoverflow.com/a/31738328/694576 (What are `a` and `b`, btw?) – alk Jul 31 '15 at 06:32
  • `a` and `b` are local variables. – Ishmeet Jul 31 '15 at 07:22
  • Also your wording is inaccurate, as "*memory address of str2*" would be `&str2`, whereas `str2 - str1` is actually referring to the address stored **in** the pointer variable `str2`. – alk Jul 31 '15 at 07:26
  • Yes, thank you @alk, I did meant address stored in the pointer variables `str2` and `str1` – Ishmeet Jul 31 '15 at 08:47
  • 1
    "address is on stack and my above answer will have different and non consecutive memory locations." is not specified by C. A "stack" is not even specified by C. That result is depends on the platform/compiler as it is undefined behavior. – chux - Reinstate Monica Aug 01 '15 at 16:41
  • You are right it is dependent on platform/compiler. That is why I have given an example in my answer for the memory location. And, the actual location is undefined behaviour for C and is different from your machine to mine. – Ishmeet Aug 03 '15 at 05:00