tags:

views:

374

answers:

6

Having very similiar code like so:

LINT_rep::Iterator::difference_type LINT_rep::Iterator::operator+(const Iterator& right)const
{
    return (this + &right);//IN THIS PLACE I'M GETTING AN ERROR
}

LINT_rep::Iterator::difference_type LINT_rep::Iterator::operator-(const Iterator& right)const
{//substracts one iterator from another
    return (this - &right);//HERE EVERYTHING IS FINE
}

err msg: Error  1   error C2110: '+' : cannot add two pointers

Why I'm getting an err in one place and not in both?

+26  A: 

Pointer addition is forbidden in C++, you can only subtract two pointers.

The reason for this is that subtracting two pointers gives a logically explainable result - the offset in memory between two pointers. Similarly, you can subtract or add an integral number to/from a pointer, which means "move the pointer up or down". Adding a pointer to a pointer is something which is hard to explain. What would the resulting pointner represent?

If by any chance you explicitly need a pointer to a place in memory whose address is the sum of some other two addresses, you can cast the two pointers to int, add ints, and cast back to a pointer. Remember though, that this solution needs huge care about the pointer arithmetic and is something you really should never do.

Michał Trybus
@Michał but as you see from def. of this operators I'm returning difference value not a pointer(iterator) but of course I'm getting the idea, and I agree with you.
There is nothing we can do
Michał Trybus
Casting to int is a bad idea, since sizeof(int) might not be sizeof(void *). Using something like ptr_diff_t would be a better choice.
Mike Weller
@Mike: I know, just gave an example, but sure, `ptrdiff_t` is a better idea. The question is, why to even bother adding two pointers?
Michał Trybus
*knows a compiler/runtime/OS combination where `sizeof(ptrdiff_t) != sizeof(void *)`*. I'd say use `[u]intptr_t` if you're going to attempt this at all.
Logan Capaldo
+3  A: 

Subtracting two pointers gives you the distance between them. What would the result of adding two pointers be?

Marcelo Cantos
I was thinking that if I can do (4 - 2) I can also do (4 + 2); Obviously it's not the case.
There is nothing we can do
A pointer to a random chunk of memory at the address indicated by the sum of the pointers' addresses? ;)
Jake Petroules
@Jake but isn't that the same if I substract bigger address from smaller address?
There is nothing we can do
Let's say you have two int pointers, ptr1 and ptr2. Then ptr1 - ptr2 = the difference between the pointers -- ie: the number of ints that the space between ptr1 and ptr2 takes up. ptr2 - ptr1 should be the same as -(ptr1 - ptr2).
cHao
@KMKY, If you can do `(date2 - date1)`, yielding a time interval, can you also do `(date2 + date1)`? What would it yield?
Marcelo Cantos
@cHao, no-one has any issues with pointer subtraction. It's addition that's causing all the fuss.
Marcelo Cantos
@Marcelo, I love your date addition example;)
Michał Trybus
@Knowing "I was thinking that if I can do (4 - 2) I can also do (4 + 2)" -> Pointers are not integers.
FredOverflow
@cHao: [(ptr1 - ptr2) vs (ptr2 - ptr1)](http://codepad.org/UqSdCXrA)
Lazer
@Marcelo: Of course addition is causing problems -- cause it's freaking stupid. "ptr1 + ptr2" HAS NO (useful) MEANING, unlike "ptr1 - ptr2", which means basically "how many times i'd have to ++ptr2 til ptr2 == ptr1". The fact that someone even came up with the idea of adding pointers demonstrates a serious lack of knowledge about the whole concept of pointers.
cHao
@cHao, thank you for joining the real discussion at last. The point of my questions was to help the OP discover the problem with their original question all by themselves, and without making them feel stupid in the process. Learning is much stronger and more durable when it comes through one's own reasoning processes instead of being spoon-fed an answer. BTW, what constitutes a _serious_ lack of knowledge about pointers, as opposed to an ordinary lack of knowledge?
Marcelo Cantos
@FredOverflow, a `vector2d` isn't an integer either, but it supports both addition and subtraction; neither is a `float`, while we're at it. So, not being an integer is hardly the reason that a type doesn't support addition.
Marcelo Cantos
@Marcelo Fine, let me rephrase: a pointer is neither a number nor a vector.
FredOverflow
@Marcelo: An ordinary lack of knowledge would be, say, being confused about what an int** would be good for, or maybe even how to get the value a pointer points at. Means someone's inexperienced with pointers, but not in a scary way. It'd take someone who doesn't even understand what pointers *are* to try and add them, and frankly, that person shouldn't be messing with pointers at all -- only confusion and segfaults down that path. A lot of people just can't understand pointers. I don't fault them for it, but i do recommend they use a language where the concept isn't practically required.
cHao
@cHao, say a person first learns programming via VBA, and then decides to try their hand at C or C++. They read a book and write code as they follow along. At the chapter on pointers, they find that you can subtract pointers but can't add them. Realising something hasn't clicked in their brain, they decide to voice the question on a programmer forum. Would you advise such a person not to bother learning C or C++, because it's just beyond them? Please don't confuse "don't understand" with "can't understand". We are all born with a serious lack of knowledge about the whole concept of pointers.
Marcelo Cantos
@cHao: one more point. To _not_ contemplate the meaning of adding pointers represents a serious lack of imagination. I thus consider it quite commendable that someone should ponder it. Whether one is able to figure out the answer oneself or requires assistance is merely a function of the level of experience one has at the time the question arises.
Marcelo Cantos
@Marcelo: RE: the VBA convert, i'd probably ask what book they were reading that so confused them about pointers. It's not a difficult concept -- at least it wasn't for me, and i don't feel special in that regard. :P It's possible that the book they got is total crap, but that's one of very few understandable reasons.If they reread and still don't get it, then yes -- i'd suggest they either get a new book or use C++/CLI, where one can get by without touching "pointers" at all. There's only so much you can teach someone who's lacking the very basics.
cHao
@cHao, you've probably been in the game too long. I've taught numerous people basic (not BASIC) programming, and pointers are far from obvious when someone first encounters them.
Marcelo Cantos
@Marcelo: RE: your other point, why can't i add dates, or multiply them for that matter? If i asked you, what would you answer? Would you explain it? COULD you, in any way that made sense? Or would you assume i was either pulling your leg, or totally not grasping the whole concept of dates? And in the latter case, how far would you go in trying to teach me? Point is, it's not imagination that causes such questions -- it's attempts to treat them as something one's used to, and to shoehorn them into mental models that simply won't fit. That's pretty much the OPPOSITE of imagination.
cHao
I started out in old-school BASIC with the line numbers. I'm told it scars people for life. :P But even back then, the VARPTR() function in the CoCo's BASIC made sense to me (even if it didn't seem too useful at the time -- it was mostly used for passing variables to machine code subroutines -- i still played with it a bit just for kicks). Maybe i'm gifted with that innate pointer knowledge no one has, but it just...eh. Seems easy. I don't get the fuss.
cHao
Ok, @cHao, I give up. You are a genius because pointers came to you as easily as a sow pisses (to co-opt Mozart), and anyone who doesn't get it on the first go is an idiot who shouldn't even bother trying.
Marcelo Cantos
@Marcelo: That's the thing. I don't think I'm special. Frankly, i HOPE i'm *not*; it'd be a pretty sad statement on the state of programming in general, if people are routinely using stuff they don't understand. And someone who doesn't get it on the first go, if the indirection confuses them a bit, that's normal. If they forget to allocate memory, that's normal. But if they didn't even get the basics like "pointer <-> address", yes, they need to either find another book or find a language that doesn't require pointers, cause it only gets more complicated from there.
cHao
+1  A: 

I suppose in your example the result you were expecting was to add or subtract a pointer to an offset to be moved, not to another pointer.

In C++ you can subtract 2 pointers (getting the offset in memory between them) or add a pointer to an integer value (moving a pointer to another memory location being incremented by value * sizeof(object_class)). Just adding 2 pointers do not make sense in C++, but if you are sure you want to add 2 memory locations adresses, just add then as unsigned integer values (using typecast).

Jorg B Jorge
Except in 64 bit compilers where sizeof(x*) > sizeof(int). There's no guarantee about the size of pointers as related to the size of any other type.
cHao
+28  A: 

742 Evergreen Terrace + 1 = 743 Evergreen Terrace

742 Evergreen Terrace - 1 = 741 Evergreen Terrace

743 Evergreen Terrace - 741 Evergreen Terrace = 2

743 Evergreen Terrace + 741 Evergreen Terrace = ???

FredOverflow
I don't get it.
Indrek
@Indrek What do you propose the result of the fourth line should be? It simply does not make sense to add two addresses.
FredOverflow
:) Nice answer. Really, I mean it.
SigTerm
@Fred: 1484 Evergreen Terrace. Duh. ;-) (I agree with @SigTerm: Good example)
James McNellis
Degrees provide an even clearer explanation, except "degrees" can mean both absolute temperature and temperature difference, so most people don't understand that they are distinct units.For example 85 degrees + 5 degrees difference=90 degrees100 degrees - 5 degrees difference=95 degrees 100 degrees - 95 degrees= 5 degrees difference 100 degrees + 50 degrees = ?
Jeremybub
@Jeremy I think "Evergreen Terrace" fits better than "degrees", because there cannot be any confusion regarding units. "Evergreen Terrace" has nothing to do with units. It's just an indicator where to start counting, analogous to the beginning of an array.
FredOverflow
+2  A: 

Other answers explained already why, what You are doing doesn't work, but my guess is, that You want to define typical operator+ for an iterator, but got lost in that attempt.

Both pointers and standard random access iterators allow to advance the pointer or iterator by an integral value. In case of iterators, an operator+ is defined, that takes an integral value as an argument and returns an iterator.

LINT_rep::Iterator LINT_rep::Iterator::operator+(int distance) const;

You can define such operator as a method, but this method will allow You to write

iterator + distance

but not

distance + iterator

To make the addition commutative You have to define a friend non-member function that takes the distance as the first parameter and an iterator object as a second

friend LINT_rep::Iterator LINT_rep::Iterator::operator+(int distance, const  LINT_rep::Iterator & rhs);
Maciej Hehl
A: 

Why I'm getting an err in one place and not in both?

Even if you were allowed to add two pointers, this:

 return (this + &right);

would point to nowhere. Think about it - this might be something like 0x00123456, and &right will be somewhere in the same range (0x00000000..0x80000000 - i.e. 0x00321321, for example). If you add them up, the resulting address will point very far away from both variables (0x00123456 + 0x00321321 == 0x00444777, which will be way too far from both "this" and &right), you might get into reserved memory (0x8xxxxxxx on win), etc. Also, pointers could overflow. Which is (probably) why it is forbidden.

If you want to add something to pointer, add integer.

SigTerm