Имена параметров могут помочь документировать использование параметров.
Рассмотрим функцию настройки памяти:
void mem_set(void *, int, int);
void mem_set(void *buffer, int value, int nbytes);
Что легче понять?
Объявление типа структуры, как написано, является локальным для прототипа функции. Как вы, вероятно, знаете (сейчас, если не раньше), вам нужно определить тип вне области действия прототипа, чтобы успешно использовать его. То есть вы должны написать:
struct st {int a;};
void fn(struct st a, struct st b);
Вы говорите:
Я полагаю, что у прототипа был этот предел, потому что мы также можем использовать некоторые имена переменных в объявлениях прототипа. Эти имена могут конфликтовать с переменными в той же области видимости (что и у прототипа функции). Как ниже.
void fn(int a);
int a;
Итак, чтобы разрешить вышеуказанные объявления, объем прототипа ограничен. (Поправьте меня, если я ошибаюсь)
Есть вероятность, что GCC с '-Wshadow' предупредит о параметре 'a', скрывающем глобальную переменную 'a' - это, безусловно, будет сделано в определении функции и может произойти в объявлении функции. Но это не обязательное предупреждение; код, как написано, является законным C - хотя и немного сомнительным из-за затенения.
В комментариях идет длительная дискуссия о том, «почему C ограничивает (мешает) вам объявить тип в списке параметров« с подтекстом », потому что C ++ позволяет это делать»:
Комментарии
Поскольку разрешено использование / ** /, программист должен быть обязан (в соответствии с практикой кодирования) добавлять надлежащие комментарии об использовании языка там. Я считаю, что должно быть «что-то» кроме оказания помощи комментариям. - Ганеш Гопаласубраманян
ОК - верь прочь. Совместимость с тем, что делал C ++, была остальной причиной, и имена аргументов были добавлены туда для улучшения читабельности. См. Страуструп «Дизайн и эволюция C ++». Обратите внимание, что имена параметров в прототипе не являются частью интерфейса - см. Обсуждение предоставления аргументов по имени вместо позиции. - Джонатан Леффлер
Я полагаю, что вопрос, который задает ОП: «какой смысл вообще иметь область действия прототипа функции?». Вы отвечаете, к сожалению, не проливает свет на это. Честно говоря, я тоже понятия не имею. Если бы они просто хотели ограничить область объявления именованных параметров (в объявлении без определения) в качестве догадок OP, они могли бы сделать это, не вводя область действия (как, например, в C ++). - AndreyT
@ AndreyT: в определении функции аргументы являются локальными по отношению к телу функции (больше невозможно скрыть аргумент по локальной переменной во внешнем блоке тела функции). Прототип логически объявляет тип внутри функции, и поэтому должен иметь область видимости, как определено - и, следовательно, тип, определенный только в прототипе функции, не может использоваться вне функции, и функция, которая не может быть вызвана, никому не приносит пользы. - Джонатан Леффлер
@ Джонатан Леффлер: Похоже, вы объясняете, почему были разрешены имена параметров («совместимость с C ++» - ОК). То, что я хотел бы знать, - это обоснование для введения «области действия прототипа функции». Почему они увидели необходимость ввести такую область? С ++ так не делает. В C ++ отсутствует область действия прототипа функции. - AndreyT
@ AndreyT Да! Мы оба тонем в одной лодке :) - Ганеш Гопаласубраманян
Встречный пример
Это показывает, что C ++ «делает это так».
#include <cstdio>
using namespace std;
extern void x(struct c {int y;} b);
void x(struct c b)
{
printf("b.y = %d\n", b.y);
}
int main()
{
struct c a;
a.y = 0;
x(a);
return(0);
}
Этот код не компилируется с G ++ (4.0.1 в MacOS X 10.5.8). Жалуется:
$ g++ -o xx xx.cpp
xx.cpp:4: error: types may not be defined in parameter types
$
Ошибка возникает на уровнях предупреждения / ошибки по умолчанию, а также на педантичных уровнях.
Так оно и естькажется справедливым и точным сказать «С ведет себя так же, как С ++» в этом контексте. Можете ли вы продемонстрировать на примере встречного счетчика, как можно определить тип в прототипе функции в C ++, указав, какой компилятор и платформа C ++ это позволяет?