views:

97

answers:

6

$5.7 -

"[..]For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a pointer to a completely defined object type and the other shall have integral or enumeration type.

2 For subtraction, one of the following shall hold: — both operands have arithmetic or enumeration type; or — both operands are pointers to cv-qualified or cv-unqualified versions of the same completely defined object type; or — the left operand is a pointer to a completely defined object type and the right operand has integral or enumeration type.

int main(){
        int buf[10];
        int *p1 = &buf[0];
        int *p2 = 0;

        p1 + p2;       // Error

        p1 - p2;       // OK
}

So, my question is why 'pointer addition' is not supported in C++ but 'pointer subtraction' is?

+3  A: 

The result of subtraction is distance (useful).

The result of adding a pointer and a distance is another meaningful pointer.

The result of adding 2 pointers is another pointer, this time meaningless though.

It's the same reason there are distinct TimeSpan and DateTime objects in most libraries.

tenfour
+3  A: 

Result of pointer subtraction is number of objects between two memory addresses. Pointer addition doesn't mean anything, this is why it is not allowed.

Alex Farber
+5  A: 

The difference between two pointers means the number of elements of the type that would fit between the targets of the two pointers. The sum of two pointers means...er...nothing, which is why it isn't supported.

Brian Hooper
+3  A: 

The first thing that comes to mind is that it doesn't make sense to do pointer addition, so it's not supported. If you have 2 pointers 0x45ff23dd, 0x45ff23ed. What does it mean to add them?? Some memory out-of-bounds. And people in standard comittee have not found good enough reasons to support stuff like that, and rather warn you at compile time about possible problem. While pointer subtraction is fine because it indicates memory distance, which is often useful.

Leonid
+1  A: 

Because adding two pointers doesn't make sense.

Consider I have two ints in memory at 0x1234 and 0x1240. The difference between these addresses is 0xc and is a distance in memory. The sum is 0x2474 and doesn't correspond to anything meaningful.

You can however, add a pointer to an integer to get another pointer. This is what you do when you index into an array: p[4] means *(p + 4) which means "the thing stored at the address 4 units past this address."

In general, you can determine the "pointerness" of an arithmetic operation by assigning each pointer a value 1 and each integer a value zero. If the result is 1, you've got a pointer; if it's 0, you've got an integer; if it's any other value, you have something that doesn't make sense. Examples:

/* here p,q,r are pointers, i,j,k are integers */
p + i; /* 1 + 0 == 1 => p+i is a pointer */
p - q; /* 1 - 1 == 0 => p-q is an integer */
p + (q-r); /* 1 + (1-1) == 1 => pointer */
Philip Potter
A: 

Because the result of that operation is undefined. Where does p1 + p2 point to? How can you make sure it points to a properly initialized memory so that it could be dereferenced later? p1 - p2 gives the offset between those 2 pointers and that result could be used further on.

celavek