В C99 он должен давать необъявленную функцию ошибка.
В C89 / 90 объявление функций не является обязательным. Если вызывается необъявленная функция, компилятор будет предполагать, что он возвращает int
, и он передаст ей аргументы после того, как подвергнет их так называемым продвижениям аргументов по умолчанию . Другими словами, компилятор попытается вывести , что это за функция, от фактического вызова. Если позже функция определяется не так, как выводил компилятор, поведение не определено. Обычно компиляторы будут жаловаться на это с предупреждением.
Это то, что вы наблюдаете в вашем случае. Когда компилятор видит вызов prn(e)
, он предполагает, что prn
является int prn(int)
функцией. Но позже выясняется, что это на самом деле void prn(double, int)
. Несоответствие вызывает предупреждение.
В этом случае вам повезло в том смысле, что вызов необъявленной функции происходит в той же единице перевода, где определена функция. Таким образом, у компилятора есть возможность сравнить вызов и определение и выдать предупреждение о конфликте. Если бы prn
было определено в каком-то другом модуле перевода, у компилятора никогда не будет возможности сравнить их, поэтому у вас будет полноценное неопределенное поведение в ваших руках.