Arrow Operator vs. Dot Operator

Go To StackoverFlow.com

31

It seems to me that C's arrow operator (->) is unnecessary. The dot operator (.) should be sufficient. Take the following code:

typedef struct {
    int member;
} my_type;

my_type   foo;
my_type * bar;
int       val;

val = foo.member;
val = bar->member;

We see that the arrow operator must be used to dereference bar. However, I would prefer to write

val = bar.member;

There is no ambiguity as to whether I am trying to pull 'member' from a structure or from a pointer to the structure. But it is easy to use the wrong operator, especially when refactoring code. (For example, maybe I am doing some complex operations on foo, so I move the code into a new function and pass a pointer to foo). I don't think I need to care whether foo is a pointer or not; the compiler can worry about the details.

So the question: wouldn't it be simpler to eliminate -> from the C language?

2012-04-05 21:36
by remline
There are billions of lines of C code in use today. It wouldn't be simple to remove anything from the C language. That said, explicitness about indirection is A Good Thing - James McNellis 2012-04-05 21:39
You're right, it is unnecessary. It is syntactic sugar for (*bar).member. By definition, we don't need any syntactic sugar. Then again, we don't need functions, either. we could just do everything with goto - jpm 2012-04-05 21:43
Yes, but it seems like syntactic sugar which makes things harder rather than easier. Functions, on the other hand, are handy. : - remline 2012-04-05 21:48
@jpm: What about recursive calls? Note that even BASIC had GOSUB, and processors have call instructions - celtschk 2012-04-05 21:54
@celtschk While you are technically correct, I hope you appreciate the pointlessness of nitpicking a facetious statement : - jpm 2012-04-05 22:01
Duplicate of Why does the arrow (->) operator in C exist? - emlai 2015-12-13 23:22


49

The 'arrow' operator is syntactic sugar. bar->member is the same as (*bar).member. One reason for the difference is maintainability. With the arrow operator distinct from the dot operator, it becomes much easier to keep track of which variables are pointers and which are not. It might be possible to always use . and have the compiler try to do the right thing, but I doubt that would make the language simpler. Trusting the compiler to interpret what you meant instead of what you literally wrote usually turns out badly.

2012-04-05 21:43
by bta
Not to mention classes that act like pointers (providing * and -> operators), but on which . is also a valid operation - jpm 2012-04-05 21:47
@jpm: C does not have classes. However you have a point insofar as this would introduce a needless incompatibility to C++ (which for the reason you state would probably not adopt that convention) - celtschk 2012-04-05 21:49
If member is itself a struct, does this equivalence between (*). and still apply? e.g. bar→member→value is the same as (*bar).member→value, but bar→(*member).value is different (in fact, it gives a compile error) - Max Coplan 2019-02-25 19:30
@MaxCoplan If member is a struct, you can't apply the * or -> operators to it. Both bar->member->value and (*bar).member->value are equivalently wrong. The only correct ways to do it would be bar->member.value or (*bar).member.value - bta 2019-02-25 23:53
@bta My bad! I meant if member is a pointer to another struct. So, ASSUMING bar→member→value is valid, (*bar).member→value will also work, but bar→(*member).value and (*bar).(*member).value will be different - Max Coplan 2019-02-26 18:04
@MaxCoplan Yes the two forms are still equivalent, but operator precedence quickly makes things quite ugly and error-prone (. and -> bind higher than *). a->b->c would become (*(*a).b).c. You really don't want to write this out the long way in a multi-level scenario - bta 2019-02-26 18:17
Explained perfectly, thank - Max Coplan 2019-02-26 18:31
(P.S. for further reading - Max Coplan 2019-02-26 20:38


6

No, it would not be easier to eliminate -> from the language, for the simple reason that megatons of code would have to be rewritten if it were. However one could define that p.x is equivalent to p->x if p is a pointer. That would be a backwards-compatible change because that code is currently illegal.

2012-04-05 21:41
by celtschk
Yes, but as @bta mentions, it would be an unwise change. -> helps significantly in determining which variables are values and which are pointers, which in turn can help keep memory management maintainable - jpm 2012-04-05 21:45
Ads