tags:

views:

234

answers:

7

I know the difference between the member operator (.) and the member by pointer operator (->).

Why did the C designers create a different operator for this access? Why can't the compiler figure it out on its own?

If you always used a . does any case exist where it is ambiguous whether you mean a member or a member by pointer?

edit: I'm not looking for the "(*a).b" syntax. I asking why didn't the designers allow you to use "a.b" instead of "a->b"?

edit: I didn't find http://stackoverflow.com/questions/1813865/why-does-c-have-a-distinction-between-and when I searched. Sorry about the dup.

+6  A: 

Would you really want the compiler to "figure it out on its own?" If it did, then the following would evaluate to the same thing (assuming p is a pointer to a struct with a member x):

(*p).x;
p.x

If the dereferencing of the pointer is implicit there, should it be implicit everywhere? Consider:

int* p;
int i = p; // should dereferencing be implicit here as well?

I think that would be far more confusing than having two separate operators.

It can also be helpful to have two operators to help keep track of how many layers of indirection you have. Granted, the -> operator is not strictly necessary for this, since p->x is equivalent to (*p).x, but it does make code a bit clearer and easier to read.

James McNellis
you'll also have to consider what should happen when additional levels of indirection are involved: do you want to allow the compiler to dereference `struct` pointers of arbitrary depth when using `.`, or restrict it to at most one level of indirection? neither solution feels 'right' to me...
Christoph
Well, since this (only `.` for `->` and `::`) is how it is done in some languages, it is possible. And it seems people coming to C or C++ from those languages find it confusing to have to differentiate.
sbi
See also [this answer](http://stackoverflow.com/questions/2843916/c-help-about-class-and-error-c3861/2843960#2843960).
sbi
@sbi: True. However, in most of those other languages, you don't really ever have to deal with the multiple levels of indirection that we have the joy of dealing with in C and C++ (there might be exceptions, but the languages that come to the top of my head don't).
James McNellis
@James: That's of course right, those languages often pretty much blur the difference between a reference and the referenced object in other regards, too. I was just pointing out that the way C and C++ treat this isn't "the one and only truly right way" and that it seems naturally only to us because we've done it for so long.
sbi
A: 

(*a).b is the same as a->b

Devel
+2  A: 

Yes the ambiguity comes from being able to override both operators. Best example maybe are shared pointers. A shared pointer can be used with . and -> operators and both have different meanings.

With -> you access the object that is pointed to and with . you access the members of the shared pointer itself.

For instance:

class MyObject {
 public:
    void myFunction() {}
 };
 boost::shared_ptr<MyObject> ptr;
 ptr.use_count(); // calls use_count, which is a member of boost::shared_ptr.
 ptr->myFunction(); // calls MyObject::myFunction, as the operator-> is overriden
haffax
A: 

Both fo->bar and (*fo).bar do the same thing!

The language simply provides an operator for indirect access, namely the arrow (->) and treats it as a single symbol.

Secko
Why was this upvoted? It doesn't answer the question.
Good Person
@Good Actually, you edited your question!
Secko
+1  A: 

When you have a language that is, at its core, intended to be a "portable assembler" you don't try to hide implementation details from the user. Of course the compiler can figure out that in the expression a.b the a in question is a pointer. Can you? Reliably? All the time? In hairy, complicated code? And can you not envision a circumstance where not being able to quickly note that a is a pointer could be a problem?

Stop thinking in terms of "hard to write" and start thinking in terms of "easy to read". (Yeah, I know. This goes against the whole C programmer mythos!) You'll be reading code a couple of orders of magnitude more often than you'll be writing it.

JUST MY correct OPINION
A: 

The -> operator is just an easier way to reference an object's method or member by its pointer, instead of using something like (*p).member or (*p).method.

Example:

MyClass *MyObj;

MyObj->method(); is better to read and understand than (*MyObj).method();

Jorg B Jorge
+1  A: 

C++ lets you overide the -> operator. When you have a smart pointer class like std::auto_ptr, the same variable might support both . and ->, on which you use . to access members of the auto_ptr, and -> to access members of the pointer which it contains.

ChrisW