Ответ 1
Объявление:
int f();
... сообщает компилятору, что некоторый идентификатор (f
в этом случае) называет функцию и сообщает ему тип возвращаемого значения функции - но не указывает число или тип параметра ( s) эта функция предназначена для приема.
Прототип:
int f(int, char);
... аналогично, но также указывает номер/тип параметра (ов), который предназначена для приема. Если он не принимает никаких параметров, вы используете что-то вроде int f(void)
, чтобы указать, что (поскольку оставить круглые скобки пустыми, это объявление). Определение функции нового стиля:
int f(int a, char b) {
// do stuff here...
}
... также выступает в качестве прототипа.
Без прототипа в области видимости компилятор применяет акции по умолчанию до аргументов перед вызовом функции. Это означает, что любой char
или short
он продвигается до int
, а любой float
продвигается до double
. Поэтому, если вы объявляете (а не прототип) функцию, вы не хотите указывать какие-либо параметры char
, short
или float
- вызов такой вещи будет/будет давать поведение undefined. С флагами по умолчанию компилятор может отклонить код, так как в принципе нет возможности использовать его правильно. Вы могли бы найти некоторый набор флагов компилятора, которые заставили бы его принять код, но это было бы совершенно бессмысленно, поскольку вы все равно не можете его использовать...