[...]
>>> In modern C, because type information is available the distinction
>>> becomes redundant. Indeed there is an analogous case where this
>>> kind of redundancy has been exploited, namely in calling through
>>> a pointer to function, eg, int (*fp)( int, int ), which can be
>>> used in an expression just like an ordinary function:
>>>
>>> blah = fp( 1, 2 );
>>>
>>> rather than
>>>
>>> blah = (*fp)( 1, 2 );
>>>
>>> Clearly a similar kind of transformation could be made with -> and .
>>
>> Exactly. This is a relic of the very earliest versions of C. and is
>> unnecessary. Essentially all languages that are derived from the C
>> syntax have discarded it. I (and many others) have suggested for years
>> that this be changed, but it has never become a priority for the
>> committee.
>
> How many levels of indirection should such a convenience be willing to
> travel?
IMHO, the only sensible answers are 0, 1, and infinity (0 being
the current rule); anything else would be too arbitrary.
I'd vote for 1, so that `foo.bar` would be valid if `foo` is either
a struct or union or a pointer to a struct or union, but not if
`foo` is a pointer to pointer.
On the other hand, I don't greatly mind leaving it at 0. Introducing
`ptr.member` in a new revision of the language would encourage
writing code that can't be compiled with older compilers, even
though it doesn't really add any expressive power. If it were
introduced, I'd advocate taking advantage of it only in new code
that inherently depends on the new standard for other reasons.
(It should be easy enough to implement in compilers that I'd expect
it to be one of the first new features implemented.)
The publication of K&R1 in 1978, or the first ANSI standard in
1989, would have been good opportunities to introduce this feature.
But now, I think that ship has sailed.
[...]