Ответ 1
В режиме строгого соответствия (это означает "теоретически" ) вы вызываете поведение undefined (что плохо) при вызове функции, которая принимает переменное количество аргументов без объявления прототипа функции в области видимости. Это означает, что компилятору разрешено делать все, что ему нравится, с программой, которая использует printf()
без прототипа из #include <stdio.h>
или эквивалентной декларации. "Все, что ему нравится" включает в себя правильную работу в качестве одного из вариантов; это вариант, выбранный вашим примером.
На практике код будет работать с большинством практических компиляторов, даже без формального объявления функции printf()
.
Как было указано qrdl, функция была найдена, потому что компилятор C связан с библиотекой C.
Обратите внимание, что комментарий Криса Янга о C99 и "неявный int" является точным, но правило "функции переменных аргументов должно иметь прототип в области видимости" относится как к C89, так и к C99. Большинство компиляторов не работают в строгом режиме совместимости с C99 по умолчанию, потому что слишком много кода, который не компилируется таким образом.
Крис Янг прокомментировал:
Крис, конечно, прав. Из стандарта C99 были удалены две функции "неявного объявления". В предисловии к стандарту перечислены их как:Чтобы пояснить, мой комментарий был о том, что C99 удаляет неявные объявления. Говоря "неявный int", я думаю, что вы имеете в виду функцию C89, разрешающую такие объявления, как foo (void); для обозначения int foo (void); или что-то 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()
были определены с эллипсисом, этот прототип понадобился бы в теории! )