Хорошо, это не имеет никакого серьезного последствия, но это подталкивало меня к
в то время как: есть ли причина различия между операторами -> и .?
Конечно, текущее правило состоит в том, что . действует на структуру, а -> действует на
указатель на структуру (или объединение). Но вот как это работает на практике.
Пусть s - структура, включающая элемент x, и пусть ps - указатель на структуру того же вида.
Если вы пишете
s->x
компилятор выдаст предупреждение на
Вы имели в виду s.x. Повторите попытку и перекомпилируйте.
Если вы пишете
ps.x
компилятор выдаст предупреждение на
Вы имели в виду ps- > x. Повторите попытку и перекомпилируйте.
Поскольку компилятор знает тип как s, так и ps во время компиляции, он имеет всю информацию, необходимую ему для интерпретации того, что будет правильным оператором. Я подозреваю, что это не похоже на другие предупреждения (например, отсутствующая точка с запятой), поскольку нет никакой двусмысленности в правильном исправлении.
Итак, вот гипотетическое предложение комитету по стандартам C1x (который никогда не будет рассмотрен, поскольку ISO находится на консервативной полосе):
Учитывая выражение lhs.rhs, если lhs является структурным или объединенным типом, то выражение должно ссылаться на элемент lhs с именем rhs. Если lhs имеет тип pointer-to-struct или -union, то это должно быть интерпретируется как (* lhs).rhs.
Это, безусловно, спасло бы нас все время и облегчило бы людям изучать C [и я научил достаточно C, чтобы сказать с полномочиями, что учащиеся находят, что -> может быть запутанным или раздражающим.]
Там даже прецедент, где C делает несколько подобных вещей. Например, для целей реализации декларации функций всегда передаются в указатель на функцию, поэтому f(x,y) и (*f)(x,y) будут работать независимо от того, была ли объявлена f как функция или указатель на функцию.
Итак, мой вопрос: что случилось с этим предложением? Можете ли вы придумать примеры, где будет фатальная двусмысленность между ps.x и s.x, или почему сохранение обязательного различия в противном случае полезно?