Неявные объявления функций иногда работают в C?
Может кто-нибудь, пожалуйста, объясните мне, почему следующие компиляции:
int main()
{
int a = mymethod(0);
}
int mymethod(int b)
{
return b;
}
но это не
int main()
{
mymethod(0);
}
void mymethod(int b)
{
return;
}
Я думал, что предварительные объявления требуются в C/C++, но вот контрпример. Как неявные объявления работают в C?
4 ответа
Я предполагаю, что когда вы говорите, что это не работает во втором примере кода, вы имеете в виду, что вы получаете ошибку во время компиляции.
Причина в том, что при неявном объявлении функции предполагается, что она принимает фиксированное количество аргументов и возвращает int
, Тем не мение, mymethod()
сначала неявно объявляется, а затем объявляется возвращаемым void
, Это ошибка, так как новое объявление не соответствует предыдущему (неявному) объявлению.
C90 (ANSI C89) допускает неявные объявления функций. Из С89, раздел 3.3.2.2:
Если выражение, которое предшествует списку аргументов в скобках в вызове функции, состоит исключительно из идентификатора, и если для этого идентификатора не видно никакого объявления, идентификатор неявно объявляется точно так, как если бы в самом внутреннем блоке, содержащем вызов функции, объявление
extern int identifier();появился.
Тем не менее, это разрешение было снято с C99 (и, следовательно, также запрещено в C11). C++ никогда не допускал неявных объявлений функций.
Неявные объявления, которые генерирует компилятор, будут предполагать, что возвращаемый тип функции int
, что иногда не то, что вы хотите. Избегайте его использования.
Обратите внимание, что неявные объявления работают только в C89, они удалены в C99. C++ также не поддерживает это.
Это может быть подтверждено стандартом C11(ISO/IEC 9899:201x).
В разделе C11 Forward перечислены все основные изменения в третьем издании (например, C11) и во втором издании (например, C99), одно из которых:
Основные изменения во втором издании:
...
- удалить неявное объявление функции
Также в Обосновании для международных стандартных языков программирования C §6.5.2.2 Вызовы функций
Новая функция C99: правило неявного объявления функций было удалено в C99. Эффект заключается в том, чтобы гарантировать создание диагностики, которая улавливает дополнительную категорию ошибок программирования. После выдачи диагностики реализация может принять неявное объявление и продолжить перевод для поддержки существующих программ, использующих эту функцию.
По умолчанию предполагается, что функция возвращает int. Так что первый сработал (к счастью), потому что так оно и было. В общем, это не так.
Для неявной функции в C99 функция должна быть объявлена до ее вызова. При объявлении напишите правильный прототип функции. Прототип объявления метода по умолчанию имеет тип возвращаемого значения "int", поэтому он отлично работает (в первом случае вашего примера) с одним предупреждением (например, "неявное объявление функции недопустимо в c99"). Но во втором случае вы изменили прототип по умолчанию, поэтому вам нужно объявить его прототип.
Например:
//Function prototype declaration
void mymethod(int);
//Implementations
int main()
{
mymethod(0);
}
void mymethod(int b)
{
return;
}