Why does C have a distinction between -> and .?

Viewed 2064

OK, this is of no serious consequence, but it's been bugging me for a while: Is there a reason for the distinction between the -> and . operators?

Of course, the current rule is that . acts on a struct, and -> acts on a pointer-to-struct (or union). But here's how it works in practice. Let s be a struct incuding an element x, and let ps be a pointer to a struct of the same form.

If you write

s->x

the compiler will spit out a warning in the way of

You meant s.x. Please retype that and recompile.

If you write

ps.x

the compiler will spit out a warning in the way of

You meant ps->x. Please retype that and recompile.

Because the compiler knows the type of both s and ps at compile time, it has all the information it needs to interpret what the correct operator would be. I suspect that this isn't like other warnings (like a missing semicolon), in that there is no ambiguity about the correct fix.

So here's a hypothetical proposal to the C1x standards committee (that would never be considered, because the ISO is on a conservative streak):

Given the expression lhs.rhs, if lhs is a struct or union type, then the expression shall refer to the element of lhs named rhs. If lhs is of type pointer-to-struct or -union, then this shall be interpreted as (*lhs).rhs.

This would certainly save us all time, and make it easier for people to learn C [and I've taught enough C to say with authority that learners find the -> thing to be either confusing or annoying.]

There's even precedent, where C does a handful of similar things. E.g., for implementation reasons, function declarations are always cast to pointer-to-function, so f(x,y) and (*f)(x,y) will both work regardless of whether f was declared as a function or a pointer to function.

So, my question: what's wrong with this proposal? Can you think of examples where there would be fatal ambiguity between ps.x and s.x, or why keeping the mandatory distinction is otherwise useful?

7 Answers
Related