-1

I know that subtracting pointers of a specific data type should return the number of items (with this specific data type), which would accommodate as whole within the memory between pointers.

I noticed that if the size of the structure is not the power of 2, the results of subtracting pointers are not what I expected. Could anyone explain to me why?

Sample code:

#include <stdio.h>
typedef struct st {
    int i;
    char c[7];
}v;

void main() {
    v *p1 = (v*) 1000;
    v *p2 = (v*) 1359;
    printf("%ld\n", p2-p1);
}

Output:

6148914691236517235
Quentin
  • 62,093
  • 7
  • 131
  • 191
piko
  • 31
  • 1
  • 6

1 Answers1

4

The behaviour of your code is undefined.

You can only subtract pointers if they point to elements within the same array, or one past the end of that array. (An object may be treated as an array of one element for the purpose of this rule.)

(v*)1000 and (v*)1359 do not satisfy that condition, so you can't subtract them.

Also, you should use %td as the format specifier for a ptrdiff_t type: which is the type of the result obtained when subtracting two pointers. Else you have more undefined behaviour.

For commentary on converting an int type to a pointer type, see Cast int to pointer - why cast to long first? (as in p = (void*) 42; )

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • It is *undefined* or *unspecified*? – JFMR Dec 22 '17 at 11:50
  • Undefined. Note that the assignment of an int to a pointer type is implementation defined, but the other issue vastly outweighs that. – Bathsheba Dec 22 '17 at 11:52
  • 2
    FYI, you use “scalar” here differently from the C standard. The C standard defines “scalar” types to be arithmetic or pointer types. For array arithmetic, any object may be treated as an array of one element. – Eric Postpischil Dec 22 '17 at 12:26
  • @EricPostpischil: Yes, and I'm sure it's not the first time my mathematical terminology has slipped into an answer. Changed, with thanks. – Bathsheba Dec 22 '17 at 13:08