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