В C было разрешено, чтобы функции не имели прототипов (объявлений). При вызове таких функций не будет преобразований параметров. Eg.:
f(0);
вызовет функцию с именем f
с параметром (int)0
, даже если f
не было объявлено. Это приводит к неопределенному поведению (... segfaults ...), когда фактическое определение f
(в другом файле .c
или в библиотеке) было, например. int f(char*)
или int f(long)
. Это не очень хорошая практика, но сохраняется для обратной совместимости с оригинальным C.
Когда присутствует прототип, компилятор автоматически преобразует параметры в требуемые типы (возможно, с ошибкой) на сайте вызова.
PS: не поймите меня неправильно, по умолчанию int
. То, что на самом деле вызывает компилятор, полностью зависит от параметров вызова. Например. f(1.1)
будет соответствовать void f(double)
, f("string")
с f(char*)
.