23

Why addition of two pointers not supported in c or c++.

When I do,

int *ptr,*ptr1;
int sum = ptr + ptr1;

C or C++ throws an error. While it supports,

int diff = ptr - ptr1;
vignesh babu
  • 297
  • 1
  • 2
  • 13
  • 6
    Ask yourself this, how would adding pointers be of any real use as opposed to subtracting them? – Jeff Mercado Sep 04 '14 at 14:08
  • What do you expect the sum to be pointing to? It's probably not supported because it's not useful (and potentially a source of bugs) – ajclinto Sep 04 '14 at 14:09
  • 7
    Think about it this way. Subtracting the number of one house in a street from the number of another house in the street gives you the number of houses between them (plus one. i.e #2 - #1 = 1 = 0 + 1). Yet if you add the number of one house to another, what exactly would you have? You can think of pointers like house numbers. The number itself is virtually meaningless - it's only a means by which to find a particular house, or in the case of pointers - it's a means to address a particular piece of memory. – enhzflep Sep 04 '14 at 14:16
  • @AndreyChernyakhovskiy Of course, that can be achieved without pointer addition `middle = begin + (end-begin)/2` – dohashi Sep 04 '14 at 14:32
  • 2
    @AndreyChernyakhovskiy Luckily we are programming and not doing mathematics! ;-) – dohashi Sep 04 '14 at 14:39
  • @AndreyChernyakhovskiy Umathematikal maybe, but definitely much more sane! There is one big problem with your approach, and that is possible and quite easy integer overflow. Substracting two pointers, especially when you know which one is the end, can never overflow. – Petr Dec 22 '16 at 15:58
  • @Petr, thanks for your necroposting, but that was supposed to be a joke. – ach Dec 22 '16 at 16:13
  • @AndreyChernyakhovskiy Sorry, I did not get the joke, and I thought maybe there is someone somewhere, who will will just copypaste it, because it seems like a nice straightforward solution. – Petr Dec 22 '16 at 16:27
  • @Petr, looks like you're right, someone else took it seriously, it seems. I chose to remove my comments to avoid unnecessary confusion. – ach Dec 23 '16 at 00:36

3 Answers3

39

Pointers contain addresses. Adding two addresses makes no sense, because you have no idea what you would point to. Subtracting two addresses lets you compute the offset between these two addresses, which may be very useful in some situations.

Edit: To address the common wish for finding the mid consider this (purely as an example):

#include <stdio.h>
int main (int argc, char **argv){
    int arr[] = {0,1,2,3,4,5,6,7,8,9};
    int *ptr_begin = arr;
    int *ptr_end = &arr[9];
    int *ptr_mid = ptr_begin + (ptr_end - ptr_begin)/2;
    printf("%d\n", *ptr_mid);
}

I am quite sure that you can always come up with an offset-computation which lets do what you want to achieve with addition.

midor
  • 5,487
  • 2
  • 23
  • 52
  • Addition makes sense in case of finding mid of an array as @Andrey_Chernyakhovskiy mentioned! – vignesh babu Sep 04 '14 at 14:27
  • Adding two pointers makes no sense: there should be a type "pointer offset". But there isn't. I cannot store it as an integer, because the size of an integer may be smaller or bigger than the size of a pointer. But the offset between two pointers will always fit in a pointer, so I will safe it as such! This could be really needed once you are working on low level, like decoding message frames. – Johan Jan 25 '19 at 10:44
  • In C++ consider `ptrdiff_t`: https://en.cppreference.com/w/cpp/types/ptrdiff_t. I can't find the the declaration/definition in C right now, and don't have time to look it up, but this is a thing in C, too, and also in the linux kernel IIRC. – midor Jan 25 '19 at 11:13
  • Also `intptr_t` and `uintptr_t` (stddef IIRC). – midor Jan 25 '19 at 11:24
  • If you know that one of the pointers is null then adding them makes perfect sense. – Šimon Hrabec Apr 29 '20 at 09:50
  • 2
    It is not correct that knowing that one of them is NULL/nullptr means this makes sense. Both C and C++ allow constants other than 0 to be the underlying value of NULL/nullptr. See https://stackoverflow.com/questions/2599207/can-a-conforming-c-implementation-define-null-to-be-something-wacky and https://stackoverflow.com/questions/54098794/is-null-guaranteed-to-be-0 – midor May 22 '20 at 09:46
  • @vigneshbabu It actually doesn’t make sense for that use case. You should not find a midpoint as `(a+b)/2`, since the addition can overflow (and it would be very likely to overflow, for pointers). See https://cs.stackexchange.com/questions/80415/why-is-binary-search-using-this-weird-thing-to-calculate-middle/80422 – Sneftel Feb 02 '21 at 08:45
  • And now we have [`std::midpoint`](https://en.cppreference.com/w/cpp/numeric/midpoint) – Caleth Feb 02 '21 at 09:14
  • The code you've provided must not work, doesn't it? We can typedef `pointer_offset` to solve this, doesn't it? – mohammadsdtmnd Apr 05 '23 at 11:28
  • Not sure why you think so. This is totally sound and complies with -Wall -Wextra with only warnings about the args to main being unused. If one wanted to explicitly type the `ptr_end - ptr_begin`, one could use `std::ptrdiff_t`, but subtraction of pointers is well defined. Feel free to comment if it doesn't work for you, but please include some form of error or the likes. – midor Apr 09 '23 at 11:39
0

Adding two addresses actually can be useful, You may need to know the middle address between two adresses for example (a+b)/2 ( for the guy who want to think of pointers as house numbers, this would give him the number of the house in the middle between the two houses ), I think that adding two addresses should be allowed because you can do it anyway using casts :

int *ptr,*ptr1;
int sum = (int)ptr + (int)ptr1;

EDIT : I'm not saying that using adding addresses is obligatory in some cases, but it can be usefull when we know how to use it.

Othman Benchekroun
  • 1,998
  • 2
  • 17
  • 36
  • 1
    In the middle between the two houses you can find garbage, memory is not necessarily contiguous and it is not necessarily handed out sequentially. – David Ranieri Sep 04 '14 at 14:48
  • 2
    Assuming contiguous memory (e.g. array) It would probably be safer to do the same "middle address" calculation with `int *ptr2 = ptr + ((ptr - ptr1) / 2)`, as it may be less susceptible to an overflow in systems where memory has reached its physical limitations based on pointer size (such as ~4GB on 32 bit systems). It is also susceptible to give misaligned pointers (e.g. finding the middle between 4-byte integers at `0x1000` and `0x100C`, resulting in `0x1006` instead of `0x1004` or `0x1008`) – Serge Sep 04 '14 at 14:53
  • 4
    Don't cast pointers to `int`, that is fundamentally wrong because they may have different width. The integer types in C for such manipulations are `uintptr_t` and `intptr_t`. – Jens Gustedt Sep 04 '14 at 15:05
  • As i said in my EDIT, this could be usefull for those who know how to use it !! @Serge x + (x-y)/2 is not the middle of [x,y] (it's not even included in [x,y], but i think you meant x + (y-x)/2 and that's equal to (x+y)/2. – Othman Benchekroun Sep 04 '14 at 15:39
  • @user3883676 yes, it was meant to say `x + (y - x)/2` – Serge Sep 04 '14 at 16:15
  • Develop it, it's equal to x/2 + y/2 – Othman Benchekroun Sep 05 '14 at 07:54
  • Good point on not casting to int... You have to cast it to `uintptr_t` for the correct result... – Raghav RV May 16 '17 at 10:59
  • This is definitely going to overflow and lead to incorrect result results on platforms where the high bit is set in addresses. – Sneftel Feb 02 '21 at 08:52
0

To put it plainly, difference between two pointers give the number of elements of the type that can be stored between the two pointers, but adding them doesn't quite give any meaningful functionality. If there's no meaningful functionality then doesn't it make sense that it is not supported.