В режиме строгого соответствия (что означает «теоретически») вы вызываете неопределенное поведение (что плохо), когда вызываете функцию, которая принимает переменное количество аргументов без объявления прототипа функции в области видимости. Это означает, что компилятору разрешено делать с программой, использующей printf()
, все, что угодно, без прототипа из #include <stdio.h>
или эквивалентного объявления. «Все, что угодно» включает в себя правильную работу как один из вариантов; это, кажется, вариант, выбранный вашим примером.
На практике код будет нормально работать с большинством практичных компиляторов даже без формального объявления функции printf()
.
Как указал qrdl, функция была найдена, потому что компилятор C связывается с библиотекой C.
Обратите внимание, что комментарий Криса Янга о C99 и «неявном int» точен, но правило о том, что «функции с переменными аргументами должны иметь прототип в области видимости», применимо как к C89, так и к C99. Большинство компиляторов по умолчанию не работают в строгом режиме совместимости с C99, потому что слишком много кода не компилируется таким образом.
Крис Янг прокомментировал:
Чтобы уточнить, мой комментарий был о том, что C99 удаляет неявные объявления. Говоря «неявный int», я думаю, вы имеете в виду функцию C89, разрешающую такие объявления, как foo(void); означать int foo(void); что-то C99 также удалил.
Крис, конечно, прав. Из стандарта C99 были удалены две функции «неявного объявления». В предисловии к стандарту они перечислены как:
- удалить неявный
int
- удалить неявное объявление функции
Я не думал (и, следовательно, не писал) достаточно ясно. Тем не менее, и C89, и C99 требуют наличия прототипа для функций, которые принимают переменное число аргументов.
Проиллюстрировать:
extern int pqr();
int main(void)
{
int i = pqr(1, 3);
return i;
}
Без первой строки это правильный фрагмент C89 с неявным объявлением функции pqr()
как функции, возвращающей целое число (с неопределенными аргументами). Если первая строка заменена на extern pqr();
, то это правильный фрагмент C89 с явным объявлением pqr()
как функции, возвращающей целое число (с неопределенными аргументами), но возвращаемый тип — «неявный int
». Как написано, функция явно объявлена и имеет явный тип возвращаемого значения int
, но она по-прежнему имеет неуказанные аргументы. Я считаю, что допустим C99 - хотя и не совсем желательно. Конечно, GCC (3.4.4) принимает его с опциями '-std=c99 -pedantic
". В идеале объявление функции должно включать полный прототип. (И, если бы pqr()
было определено с многоточием, этот прототип потребовался бы теоретически эм>!)
person
Jonathan Leffler
schedule
04.12.2008
main()
. C99 позволяет вам опускатьreturn 0;
или его эквивалент в концеmain()
. - person Jonathan Leffler   schedule 30.10.2015