Задача определения функции стиля K & R - PullRequest
14 голосов
/ 29 января 2011

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

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 Ответ

22 голосов
/ 29 января 2011

На самом деле, довольно интересный вопрос.

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

Inв обоих случаях у вас есть определение эпохи K & R для foo(), но ранее было объявление C99 (с прототипом).

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

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

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

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

...