tags:

views:

150

answers:

4

Consider

#include <cstdio>

int main() {
    char a[10];
    char *begin = &a[0];
    char *end = &a[9];
    int i = end - begin;
    printf("%i\n", i);
    getchar();
}

#include <cstdio>

int main() {
    int a[10];
    int *begin = &a[0];
    int *end = &a[9];
    int i = end - begin;
    printf("%i\n", i);
    getchar();
}

#include <cstdio>

int main() {
    double a[10];
    double *begin = &a[0];
    double *end = &a[9];
    int i = end - begin;
    printf("%i\n", i);
    getchar();
}

All the above three examples also print 9

May I know, how I should interpret the meaning of 9. What does it mean?

+12  A: 

9 means the number of elements of type 'T' between &a[9] and &a[0] (where T is char, int, double respectively in that order).

The actual number of bytes between them is (&a[9] - &a[0])*sizeof(T). Note that sizeof(char) is 1 by definition. Note further that a byte is not mandated to be 8-bits. Instead it is a number of 8-bit memory locations required to hold all the characters in the implementations' basic character set.

EDIT: As @pmg pointed out, a byte is defined to be a memory location wide enough to hold all the characters in the implementation's basic character set.

Chubsdad
A byte can be 9 bits, or 36 bits, ... it doesn't need to be a multiple of 8 bits. All implementation have a predefined macro constant that specifies, for that implementation, how many bits there are in a byte: CHAR_BIT.
pmg
@pmg: Yes. Thanks for pointing it out. Have corrected the post
Chubsdad
+6  A: 

Difference between pointers to some type is number of instances between them (that is it is equivalent to difference between array indexes). Or in other words it is equivalent to (not sure about correct integer type)

((int)end - (int)begin)/sizeof(type)

6.5.6.9 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

Vladimir
The standard quote is pretty clear - it's the difference of the array subscripts.
caf
+3  A: 

the compiler will automatically calculate pointer arithmetic based on type of pointer, which is why you cant perform operation using void* (no type information) or mixed pointer type (ambiguous type).

In MSVC2008 (and in most other compiler i believe), the syntax is interpreted as calculate the amount of element difference between two pointer.

int i = end - begin;
00411479  mov         eax,dword ptr [end] 
0041147C  sub         eax,dword ptr [begin] 
0041147F  sar         eax,3 
00411482  mov         dword ptr [i],eax 

Since the subtraction is followed by a right-shifting, the result will be round-down, hence guarantee N element can fit into memory space between two pointer (and there might be unused gap). This is proven in code below which yield result of 9 too.

int main()
{
    double a[10];
    double *begin = &a[0];
    char *endc = (char*)&a[9];
    endc += 7;
    double *end = (double*)endc;
    int i = end - begin;
    printf("%i\n", i);
    getchar();

    return 0;
}
YeenFei
Wow. Assembly code. Just miss them.
Yan Cheng CHEOK
+3  A: 

Just think at the definition of subtraction: if, in general

r = b - a

it means that

b = a + r

It holds the same for pointers:

ptrdiff_t res = end - begin;

thus

end == begin + res

Now, knowing the normal pointer arithmetic rules, you can easily deduce that res is the number of elements (of the type pointed to by begin and end) that separate begin and end.


Notice that I didn't use int as the type of res, but ptrdiff_t: this is very much intentional, since ptrdiff_t is defined to be "the type returned by the subtraction operation between two pointers" (link), so it's the perfect type to hold such result.

Matteo Italia
+1 for mentioning `ptrdiff_t`
Jens Gustedt