Почему #include <stdio.h> не требуется, чтобы использовать printf ()?

31
задан vaxquis 30 October 2015 в 02:30
поделиться

3 ответа

В строгом режиме соответствия (который означает "в теории"), Вы вызываете неопределенное поведение (который плох), когда Вы вызываете функцию, которая берет переменное количество аргументов без объявления прототипа функции в объеме. Это означает, что компилятору позволяют сделать что-либо, что он любит с программой, которая использует printf() без прототипа от #include <stdio.h> или эквивалентное объявление. "Что-либо, что это любит", включает работу правильно одной из опций; это, кажется, опция, выбранная Вашим примером.

На практике, код будет работать хорошо с большинством практических компиляторов даже без формального объявления эти printf() функция.

, Как был указан qrdl, функция была найдена, потому что компилятор C связывается с библиотекой C.

Примечание, что комментарий Chris Young о C99 и 'неявном интервале' точен, но правило о 'функциях аргументов переменной должно иметь прототип в объеме', относится и к C89 и к C99. Большинство компиляторов не работает в строгом режиме эмуляции C99 по умолчанию, потому что существует слишком много кода, который не скомпилировал бы как этот.

Chris Young прокомментировал:

Для разъяснения мой комментарий был на C99, удаляющем неявные объявления. Путем высказывания "неявного интервала", я думаю, что Вы обращаетесь к функции C89 разрешения объявлений, таких как нечто (пусто); означать международное нечто (пусто); что-то C99 также удалено.

Chris, конечно, корректен. Было две функции 'неявного объявления', удаленные из стандарта 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() были определены с замещающим знаком, то тот прототип требовался бы в теории !)

32
ответ дан 27 November 2019 в 21:48
поделиться

Вы первоначально отметили этот C++, но это, будет казаться, будет программой C. C автоматически предоставит неявное объявление для функции, если не будет никакого прототипа в объеме (такой как из-за пропуска #include < stdio.h>). Неявное объявление было бы:

int printf();

Подразумевать, что printf является функцией, которая возвращает интервал и может взять любое количество аргументов. Этот прототип, оказалось, работал на Ваш вызов. Вы должны #include < stdio.h>

Наконец, я должен добавить, что текущий стандарт C (ISO/IEC 9899:1999 или в разговорной речи "C99") делает не , позволяют неявные объявления, и эта программа не соответствовала бы. Неявные объявления были удалены. Я полагаю, что Ваш компилятор не поддерживает C99. C++ также требует корректных прототипов и не делает неявных объявлений.

37
ответ дан 27 November 2019 в 21:48
поделиться

printf() расположен в стандартной библиотеке для C, и компоновщик всегда связывает стандартную библиотеку с Вашим исполняемым файлом, таким образом, любые стандартные функции будут найдены и не будет никаких проблем соединения.

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

9
ответ дан 27 November 2019 в 21:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: