В C пустой список параметров в функции объявление означает, что функция принимает неопределенное количество аргументов - в определении это означает, чтопринимает нет аргументов:
void foo(); // declaration, number of arguments is unspecified
void foo() // definition, number of arguments is zero
{
...
}
Список параметров void
как в объявлении, так и в определении означает, что функция не принимает аргументов:
void foo( void ); // declaration, number of arguments is 0
void foo( void ) // definition, number of arguments is 0
{
...
}
Итакпочему это так?
Ни синтаксис объявления прототипа, ни ключевое слово void
изначально не были частью C - не было никакого способа указать "эта функция не возвращает значение" и "эта функция принимает этомного аргументов такого типа ". В начале мелового периода определения функций были записаны как
foo( a, b, c ) // return type of int assumed
T a; // for arbitrary types T, Q, R
Q b;
R c;
{
// do something interesting with a, b, and c
}
, а соответствующее объявление было просто записано как
foo(); // strictly not necessary, since the compiler would assume a return type of int
C, изначально не имевшего механизма для проверки количества и типов аргументов вфункция вызов против объявления функции. Если вы назвали foo
как
foo( x, y, z, oops );
, то компилятор не сможет сказать вам, что вы передали слишком много аргументов или что любой из x
, y
или z
былНеправильный тип. Вы не знали бы, что была проблема до времени выполнения.
Стандарт 1989 года ввел ключевое слово void
вместе с синтаксисом прототипа функции, так что теперь вы можете указывать количество и типы параметров в функции объявление , что позволяет компилятору обнаруживать несоответствия, такие каквышеприведенное:
void foo( T, Q, R ); // only need to specify types in a declaration
void foo( T a, Q b, R c )
{
// do something interesting with a, b, c
}
и ключевое слово void
в качестве списка параметров означают, что функция принимает параметры no :
void foo( void );
Поскольку устаревший код существует вечноопределения и объявления функций старого стиля по-прежнему поддерживаются, хотя неявная типизация int
больше не поддерживается. Вот почему вы все еще можете объявить функцию как void foo();
, хотя лучше всего объявлять ее как void foo( void );
, если она не принимает аргументов. В противном случае, если вы попытаетесь вызвать foo
с аргументом, подобным
foo( x );
, компилятор не сможет обнаружить несоответствие.