А8.6.3. Объявители функций
В новом способе объявление функции T D, где D имеет вид
D1(список-типов-параметров)
и тип идентификатора объявления T D1 есть "модификатор-типа T", тип идентификатора в D есть "модификатор-типа функция с аргументами список-типов- параметров, возвращающая T". Параметры имеют следующий синтаксис:
список-типов-параметров: список-параметров
список-параметров , ...
список-параметров: объявление-параметра
список-параметров, объявление-параметра
объявление-параметра: спецификаторы-объявления объявитель
спецификатор-объявления абстрактный-объявительнеоб
При новом способе объявления функций список параметров специфицирует их типы, а если функция вообще не имеет параметров, на месте списка типов указывается одно слово - void. Если список типов параметров заканчивается многоточием ",...", то функция может иметь больше аргументов, чем число явно описанных параметров. (См. )
Типы параметров, являющихся массивами и функциями, заменяются на указатели в соответствии с правилами преобразования параметров (). Единственный спецификатор класса памяти, который разрешается использовать в объявлении параметра, - это register, однако он игнорируется, если объявитель функции не является заголовком ее определения. Аналогично, если объявители в объявлениях параметров содержат идентификаторы, а объявитель функции не является заголовком определения функции, то эти идентификаторы тотчас же выводятся из текущей области видимости.
При старом способе объявление функции T D, где D имеет вид
D1(список-идентификаторовнеоб)
и тип идентификатора объявления T D1 есть "модификатор-типа Т", тип идентификатора в D есть "модификатор-типа функция от неспецифицированных аргументов, возвращающая Т". Параметры, если они есть, имеют следующий вид:
список-идентификаторов: идентификатор
список-идентификаторов, идентификатор
При старом способе, если объявитель функции не используется в качестве заголовка определения функции (), список идентификаторов должен отсутствовать. Никакой информации о типах параметров в объявлениях не содержится.
Например, объявление
int f(), *fpi(), (*pfi)();
объявляет функцию f, возвращающую число типа int, функцию fpi, возвращающую указатель на число типа int, и указатель pfi на функцию, возвращающую число типа int. Ни для одной функции в объявлении не указаны типы параметров; все функции описаны старым способом.
Вот как выглядит объявление в новой записи:
int strcpy(char *dest, const char *source), rand(void);
Здесь strcpy - функция с двумя аргументами, возвращающая значение типа int; первый аргумент - указатель на значение типа char, а второй - указатель на неизменяющееся значение типа char. Имена параметров играют роль хороших комментариев. Вторая функция, rand, аргументов не имеет и возвращает int.
Объявители функций с прототипами параметров - наиболее важное нововведение ANSI-стандарта. В сравнении со старым способом, принятым в первой редакции языка, они позволяют проверять и приводить к нужному типу аргументы во всех вызовах. Следует однако отметить, что их введение привнесло в язык некоторую сумятицу и необходимость согласования обеих форм. Чтобы обеспечить совместимость, потребовались некоторые "синтаксические уродства", а именно void, для явного указания на отсутствие параметров.
Многоточие ", ..." применительно к функциям с варьируемым числом аргументов - также новинка, которая вместе со стандартным заголовочным файлом макросов <stdarg.h> формализует неофициально используемый, но официально запрещенный в первой редакции механизм. Указанные способы записи заимствованы из языка C++.