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