Проблема определения функции стиля K & R

Работает следующий код:

int main()
{
   void foo(int);
   foo(3);
   return 0;
}
void foo(a) int a;
{
   printf("In foo\n");
}

но этого нет:

int main()
{
   void foo(float);
   foo(3.24);
   return 0;
}
void foo(a) float a;
{
   printf("In foo\n");
}

Почему это происходит?

Ответ 1

Собственно, интересный вопрос.

Это связано с эволюцией языка C и тем, как он устраивается, чтобы быть обратно совместимым с более старыми ароматами.

В обоих случаях у вас есть определение K & R-era для foo(), но декларация C99 (с прототипом) ранее.

Но в первом случае параметр по умолчанию int фактически является параметром, поэтому вызов функции совместим.

Во втором случае, однако, определение K & R вводит правило стандартных правил продвижения акций из эры K & R, а тип параметра действительно double.

Но вы использовали современный прототип на сайте вызова, сделав его float. Таким образом, код на сайте вызова мог бы подтолкнуть реальный float, который в любом случае представляет собой отдельный тип из double.

Если все ссылки на foo() были в стиле K & R, я считаю, что большинство из них вы получите предупреждение, которое тогда и сделали бы компиляторы, и компилятор должен действовать таким образом, чтобы скомпилировать устаревший код. Это даже был бы безопасный тип, потому что поплавки были бы увеличены до удвоения, по крайней мере, для интерфейса вызова процедуры. (Не обязательно для внутреннего кода функции.)