как определение функции после ее использования в интерпретируемом вызове функции?

Рассмотрите этот код:

int main()
{
        int e;
        prn(e);
        return 0;
}

void prn(double x,int t)
{
}

То, почему делает этот код, дает соблюдающие предупреждения и никакие ошибки?

m.c:9: warning: conflicting types for ‘prn’  
m.c:5: note: previous implicit declaration of ‘prn’ was here

Разве это не должно давать "неопределенную функциональную" ошибку?

5
задан Sandip 11 March 2010 в 00:52
поделиться

2 ответа

В C99 должна выдаваться ошибка необъявленная функция .

В C89 / 90 объявление функций не является обязательным. Если вызывается необъявленная функция, компилятор будет считать, что она возвращает int , и передаст ей аргументы после того, как подвергнет их так называемому продвижению аргументов по умолчанию . Другими словами, компилятор попытается вывести , что это за функция, из фактического вызова. Если позже функция определяется иначе, чем то, что определил компилятор, поведение не определено. Обычно компиляторы будут жаловаться на это с предупреждением.

Это то, что вы наблюдаете в вашем случае. Когда компилятор видит вызов prn (e) , он предполагает, что prn - это функция int prn (int) .Но позже он обнаруживает, что на самом деле это void prn (double, int) . Несоответствие вызывает предупреждение.

В этом случае вам повезло в том смысле, что вызов необъявленной функции происходит в той же единице трансляции, где функция определена. Таким образом, компилятор имеет возможность сравнить вызов и определение и выдать предупреждение о конфликте. Если бы prn был определен в какой-то другой единице трансляции, у компилятора никогда не было бы возможности сравнить их, так что у вас на руках было бы полноценное неопределенное поведение.

11
ответ дан 18 December 2019 в 09:49
поделиться

C89 имеет неявные объявления функций. Если вы используете функцию без ее объявления, компилятор предполагает, что это int prn () . Когда оказывается, что это неверно (поскольку типы возвращаемых данных различаются), он сообщает вам об этом.

Обратите внимание, что пустой список аргументов в объявлении функции означает «параметры не указаны», а не «без параметров». Тогда вы обязаны убедиться, что входные параметры совпадают между вызывающим и вызываемым (чего здесь нет), и вы можете вообще не получить помощи от компилятора в этом.

В C99 эта «функция» была удалена. Я думаю, что это было действительно только в C89 для совместимости с древним кодом C. Было время, когда у C вообще не было прототипов функций, вам всегда приходилось делать все самостоятельно.

6
ответ дан 18 December 2019 в 09:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: