lex
lex

Reputation: 1279

How to understand the output?

int a[2][3];
cout << a+1 << " " << a << " " << (a+1) - a << endl;

Output:

0029FAC0 0029FAB4 1

Shouldn't (a+1)-a be 0029FAC0-0029FAB4=12 ?

Upvotes: 2

Views: 170

Answers (6)

paxdiablo
paxdiablo

Reputation: 881623

No, because pointer arithmetic is scaled depending on the thing you're pointing to. In this case, you're pointing to a three-element array of integers, each four bytes long, for a total of twelve bytes. But that's scaled back to one "element" in your arithmetic.

It's the same reason that you get 0029FAC0 rather than 0029FAB5 (0029FAB4 + 1 when it's not scaled) when printing out a+1.

If you change your output line to:

cout << a+1                 << " "
     << a                   << " "
     << (a+1) - a           << " "
     << (int)(a+1)-(int)(a) << endl;

you'll see the scaling disappear in the final term because it's no longer a subtraction of pointers:

0xbfaa0ad4 0xbfaa0ac8 1 12

Keep in mind that the a+1 in (int)(a+1) is still scaled since a is still a pointer there. It's only the subtraction that's not scaled because, at that point, both values have been converted to integers (and the usual caveats apply to converting between pointers and integers, it's safe for my particular implementation but C99 doesn't mandate that).

Upvotes: 9

Karl Knechtel
Karl Knechtel

Reputation: 61527

When you print out a pointer, it's basically implicitly cast to an integer for display, using the byte address.

When you subtract pointers, the result is a ptrdiff_t, which is already an integral type. You can only subtract pointers of the same type, and the sizeof the type is factored into the calculation. The result is the number of elements between the two pointers, not the number of bytes. (Keep in mind that if the two pointers are not pointing into the same array, the subtraction is undefined behaviour.)

In your case, the pointer type is "pointer to array of 3 ints", and your two pointers are to two adjacent elements in an array of 2 of those (array of 3 ints). They are 1 element apart, but 12 bytes apart.

Upvotes: 0

comingstorm
comingstorm

Reputation: 26117

Just as (pointer + N) points to the Nth data element after the pointer argument, going the other way with (pointerA - pointerB) gives you the number of data elements betweeen the pointers. In this case, the data element is int[3] (which you apparently already know since you are expecting 12...).

You shouldn't expect the difference in raw address value (which is machine-dependent in general anyway). C/C++ is converting for you.

Upvotes: 1

zsalzbank
zsalzbank

Reputation: 9857

I would think that the compiler is changing that to a constant.

Try b = a + 1 and then cout << b << b - a << endl;

Upvotes: 0

Falmarri
Falmarri

Reputation: 48577

Why would it be 12?

x+1-x=y

y can't possibly be 12, be this pointer arithmetic or integer.

Upvotes: -3

ulidtko
ulidtko

Reputation: 15570

Pointer arithmetic is still valid arithmetic ;-)

And as in valid arithmetic, it holds that (x+1)-x = x - x + 1 = 1.

So in your case (a+1) means not pointer to second element of an array, but pointer to the byte after the end of the array.

Upvotes: 0

Related Questions