Почему C допускает отсутствующие объявления функций?

Сегодня мы столкнулись с необычным явлением: коллега вызывал в своем коде нормально функционирующую функцию, которая вызывала segfault в libc (gethostbyname). Удивительно было то, что та же самая функция без проблем работала в других исходных файлах в той же среде выполнения. Удивительно, но segfault исчез при использовании valgrind, на самом деле он отлично работал с valgrind, без сообщений об ошибках.

После многих жертв, чтобы успокоить богов компилятора, мы в конце концов поняли, что заголовочный файл, объявляющий функцию, отсутствует в исходном файле, вызывающем функцию. Как только мы добавили это, все заработало нормально.

Почему gcc/ld не выдавал ошибку (или даже предупреждение), указывающую на то, что функция не распознана? Почему это работало с valgrind?

Спасибо.


person Gearoid Murphy    schedule 27.07.2012    source источник
comment
PS: C не позволяет отсутствовать функции (неразрешенные символы должны быть диагностированы). Я позволил себе изменить заголовок на отсутствующие функции объявления.   -  person Jens    schedule 27.07.2012


Ответы (1)


Поскольку вы не использовали правильные параметры предупреждения, такие как -Wall -Wmissing-prototypes -Wstrict-prototypes. По умолчанию gcc довольно либерален в том, что он принимает. В языке C (по крайней мере, в C89) есть концепция неявных объявлений функций, когда функция без прототипа имеет тип возвращаемого значения и список аргументов, полученные при первом использовании в вызове функции, а без этого, она возвращает int и принимает неопределенное, но фиксированное количество аргументов (т.е. не может быть функцией с переменным числом аргументов).

person Jens    schedule 27.07.2012
comment
Тяжело сказать. Был ли отсутствующий прототип стандартной функции C, возможно, malloc()? Как называлась функция? - person Jens; 27.07.2012
comment
Это была простая функция C, локальная для проекта. - person Gearoid Murphy; 27.07.2012
comment
Бьет меня тогда; У меня есть лишь смутное представление о valgrind, а небольшие знания — опасная вещь... так что лучше не строить догадки. Эмпирическое правило: максимально повышайте уровень предупреждения. - person Jens; 27.07.2012
comment
Предложите -Wall и -Werror. Эти два со временем сделают вас намного лучшим программистом. - person sherrellbc; 24.01.2018
comment
@sherrelbc Согласен, но обратите внимание, что -Wall не включает предупреждающие флаги, упомянутые в этом ответе. - person Zitrax; 31.01.2019