Поделиться через


Прототипы функций

Объявление функции предшествует определению функции и указывает имя, тип возвращаемого значения, класс хранения и другие атрибуты функции. Чтобы быть прототипом, объявление функции также должно устанавливать типы и идентификаторы для аргументов функции.

Синтаксис

declaration:
declaration-specifiers attribute-seq выбиратьinit-declarator-listвыбирать;

/* attribute-seq opt is microsoft-specific */

declaration-specifiers:
storage-class-specifier declaration-specifiers выбирать
type-specifier declaration-specifiers выбирать
type-qualifier declaration-specifiers выбирать

init-declarator-list:
init-declarator
init-declarator-list , init-declarator

init-declarator:
declarator
declarator = initializer

declarator:
pointer выбиратьdirect-declarator

direct-declarator: /* Декларатор функции */
direct-declarator ( parameter-type-list ) /* Декларатор нового стиля */
direct-declarator ( identifier-list выбирать) /* Устаревший декларатор */

Прототип имеет ту же форму, что и определение функции, за исключением того, что она завершается точкой с запятой сразу после закрывающей скобки и поэтому не имеет тела. В любом случае возвращаемый тип должен согласиться с типом возвращаемого значения, указанным в определении функции.

Прототипы функций имеют следующее важное использование:

  • Они устанавливают тип возвращаемого значения для функций, возвращающих типы, отличные intот . Хотя функции, возвращающие int значения, не требуют прототипов, рекомендуется использовать прототипы.

  • Без полных прототипов выполняются стандартные преобразования, но попытка проверить тип или количество аргументов с числом параметров не выполняется.

  • Прототипы используются для инициализации указателей на функции перед определением этих функций.

  • Список параметров используется для проверки того, что аргументы в вызове функции соответствуют параметрам в определении функции.

Преобразованный тип каждого параметра определяет интерпретацию аргументов, которые вызывает функция в стеке. Несоответствие типа между аргументом и параметром может привести к неправильному интерпретации аргументов в стеке. Например, на 16-разрядном компьютере, если 16-разрядный указатель передается в качестве аргумента, то объявляется как long параметр, первые 32 бита в стеке интерпретируются как long параметр. Эта ошибка создает проблемы не только с параметром long , но и со всеми последующими параметрами. Эти ошибки можно обнаружить, объявив полные прототипы функций для всех функций.

Прототип устанавливает атрибуты функции. Затем вызовы функций, предшествующие определению функции (или происходящие в других исходных файлах), можно проверить наличие несоответствий типа аргумента и возвращаемого типа. Например, если указать static описатель класса хранилища в прототипе, необходимо также указать static класс хранилища в определении функции.

Полные объявления параметров (int a) можно смешать с абстрактными деклараторами (int) в том же объявлении. Например, следующее объявление является законным:

int add( int a, int );

Прототип может включать как тип, так и идентификатор для каждого выражения, передаваемого в качестве аргумента. Однако такие идентификаторы находятся только в области до конца объявления. Прототип также может отражать тот факт, что число аргументов является переменной или что аргументы не передаются. Без такого списка могут быть выявлены несоответствия, поэтому компилятор не может создавать диагностические сообщения о них. Дополнительные сведения о проверке типов см. в разделе "Аргументы".

Область прототипа в компиляторе Microsoft C теперь соответствует ANSI при компиляции с параметром компилятора /Za . Если вы объявляете или тег structunion в прототипе, тег вводится в этой области, а не в глобальной области. Например, при компиляции с /Za соответствием ANSI нельзя вызывать эту функцию, не получая ошибку несоответствия типов:

void func1( struct S * );

Чтобы исправить код, определите или объявите глобальную structunion область до прототипа функции:

struct S;
void func1( struct S * );

В разделе /Zeтег по-прежнему вводится в глобальной области.

См. также

Функции