На самом деле, довольно интересный вопрос.
Это связано с эволюцией языка C и его обратной совместимостью со старыми разновидностями.
В обоих случаях у вас есть определение эпохи K&R для foo()
, но объявление C99 (с прототипом) раньше.
Но в первом случае параметр int
по умолчанию фактически является параметром, поэтому вызов функции совместим.
Во втором случае, однако, определение K&R вводит стандартное правило повышения аргумента из эпохи K&R, и тип параметра действительно double
.
Но вы использовали современный прототип на месте вызова, сделав его float
. Таким образом, код на месте вызова мог вытолкнуть настоящий float
, который в любом случае отличается от double
.
Если бы все ссылки на foo()
были в стиле K&R, я полагаю, что максимум, что вы получили бы, было бы предупреждением, что компиляторы сделали бы тогда, и компилятор должен действовать таким образом, чтобы скомпилировать унаследованный код. Это был бы даже типобезопасный вызов, потому что все числа с плавающей запятой были бы повышены до двойных, по крайней мере, для интерфейса вызова процедуры. (Не обязательно для кода внутренней функции.)
person
DigitalRoss
schedule
29.01.2011