You want to know what drives me nuts? Of course you do. char *foo declares a variable which stores an address. *foo looks up the value at the address stored in a variable. &foo gets the address of a variable.
And now this is required: foo->bar.
Is there some reason we not only need to give * two different meanings, but also need to introduce two more types of line noise? Was there anything stopping us from having an address operator that worked on both these types of data, and automatically dereferencing pointers? Of course there wasn't. Except that would have been too logical.