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

I don't think there's anything crazy about what you've said. Using . for pointers to structs would work.

However, I like the fact that pointers to structs and structs are treated differently.

It gives some context about operations and clues as to what might be expensive.

Consider this snippet, imagine that it's in the middle of a reasonably large function.

s.c = 99;
f(s);

assert(s.c == 99);

Currently I can tell that s is a struct. I know that it's going to be copied in its entirety for the call to f. I also know that that assert can't fire.

If using . with pointers to struct were allowed, I wouldn't know any of that and the assert might fire, f might set s.c (err s->c) to something else.

The other downside is that it would reduce compatibility with C++. C++ allows -> to be overloaded by classes so that classes can be 'like' pointers. It's important that . and -> behave differently. "New" C code that used . with pointers to structs would no probably not be acceptable as C++ code any more.


Well there clearly isn't any ambiguity or the proposal couldn't be made. The only issue is that if you see:

p->x = 3;

you know p is a pointer but if you allow:

p.x = 3;

in that circumstance then you don't actually know, which could potentially create problems, particularly if you later cast that pointer and use the wrong number of levels of indirection.


A distinguishing feature of the C programming language (as opposed to its relative C++) is that the cost model is very explicit. The dot is distinguished from the arrow because the arrow requires an additional memory reference, and C is very careful to make the number of memory references evident from the source code.