Я тестирую следующий код в Code :: Blocks v 12.11:
#include <stdio.h>
int main()
{
display();
return 0;
}
void display()
{
printf("\nHi");
}
Он успешно компилируется и работает хорошо. Я не могу понять, почему? Мои запросы следующие:
Функция или переменная должна быть объявлена, по крайней мере, до использования в C/C++. Здесь нет объявления, прежде чем мы вызываем функцию display().
По умолчанию все функции имеют тип возвращаемого значения как int.So, я ожидаю ошибку компиляции здесь, но он прошел успешно. Компилятор предположил бы, что display() будет int display(), а затем мы определили его как void display(),
Ваш код отлично работает как.c файл и показывает ошибку, когда он выполняется как.cpp файл. Надеюсь, что этот пост объясняет, почему.
В C++ функции должны быть объявлены или определены перед использованием; этот код не может быть C++.
В C89 или pre-standard C, если компилятор встречает идентификатор, за которым следует открытая скобка, это вызов функции, и если в нем нет объявления или определения, тогда тип возврата неявно является int
а число и типы аргументы не определены. (Таким образом, в примере display()
- это функция, возвращающая int
и принимающая неопределенное, но не переменное число аргументов.)
В C99 или C11, в любом режиме строгого соответствия, перед вызовом вы должны иметь объявление или определение функции в области. Он все еще не должен быть прототипом (inferred declaration int display();
не является прототипом, и определение также не является прототипом - для int display(void)
прототипа нужно будет int display(void)
).
Из-за выводимого типа для display()
и противоречивого определения, я думаю, вы должны получить ошибку компиляции. Это было бы в лучшем случае неаккуратным компилятором, который разрешил бы это, даже в режиме C89. Действительно, я думаю, что даже предстандартный компилятор должен жаловаться на разницу между предполагаемыми и фактическими типами возврата, но, конечно, не было стандартного, поэтому вы не могли жаловаться (и, в любом случае, этому стандарту исполнилось 24 года - компиляторы, которые поддерживают только граничащие с архаикой).
Какой компилятор (и версия) вы используете на какой платформе?
GCC 4.8.2 на Mac OS X 10.9, даже если это возможно как можно более разрешительно, говорит:
dec.c:9:6: warning: conflicting types for ‘display [enabled by default]
void display()
^
dec.c:5:5: note: previous implicit declaration of ‘display was here
display();
^
-pedantic-errors
или, в идеале, -pedantic-errors
компилировать все с помощью -Werror
(чтобы все ошибки -pedantic-errors
как предупреждения) и содержите ваш код в чистоте (er).