В классическом C вам не нужен прототип для вызова функции. Компилятор определит, что функция возвращает int и принимает неизвестное количество параметров. Это может работать на некоторых архитектурах, но не получится, если функция вернет что-то отличное от int, например структуру, или если есть какие-либо преобразования параметров.
В вашем примере виден сон, а компилятор принимает прототип, подобный
int sleep();
Обратите внимание, что список аргументов пуст. В C это не то же самое, что void. Это на самом деле означает «неизвестно». Если бы вы писали код на языке K & R, вы могли бы иметь неизвестные параметры через код, такой как
int sleep(t)
int t;
{
/* do something with t */
}
Это все опасно, особенно на некоторых встроенных чипах, где способ передачи параметров для непрототипированной функции отличается от способа с прототипом.
Примечание: прототипы не нужны для связи. Обычно компоновщик автоматически связывается с библиотекой времени выполнения C, например, glibc в Linux. Связь между вашим использованием sleep и кодом, который его реализует, возникает во время соединения еще долго после обработки исходного кода.
Я бы посоветовал вам использовать функцию вашего компилятора, чтобы требовать прототипы, чтобы избежать подобных проблем. С GCC это аргумент командной строки -Wstrict-prototypes. В инструментах CodeWarrior это был флаг «Требовать прототипы» на панели компилятора C / C ++.