2016-02-08 4 views
0

Как новичок в C, я что-то экспериментировал, поэтому исключил стандартную библиотеку <stdio.h> и до сих пор нет ошибки. Может кто-нибудь объяснить это?Почему нет ошибки после исключения стандартной библиотеки?

Вот пример кода:

main() 
{ 
    printf("hello, world!\n"); 
} 

Эта программа работает так же с или без библиотеки. Зачем?

+1

Вы видите предупреждение? –

+0

В журнале построения нет предупреждений. – mssirvi

+0

Затем вы должны использовать все флаги компилятора для включения предупреждений ... –

ответ

2

TL; DR - Вы исключаете файл заголовка, а не стандартную библиотеку.


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

В этом случае (недействительным в соответствии с последними стандартами) предполагается, что функция вернет int, и никакая проверка количества переданных параметров будет отсутствовать.

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

Таким образом, он успешно заканчивает соединение, и работает так же.

Это должно быть int main(void), по крайней мере, соответствовать стандартам.

+0

Код вызывает UB, вызывая переменную функцию без прототипа (даже в C89), было бы хорошо, если бы ваш ответ упоминал об этом. Он может очень хорошо «не работать» –

+0

@M.M Matt sir, у меня нет копии C89, поэтому я не добавил эту часть. В любом случае, я упомянул _invalid_, поскольку это нестандартно. Я посмотрел в 6.5.2.2, C11, но не получил точную цитату, чтобы поддержать UB. Не могли бы вы поделиться своим мнением? –

+0

@ M.M: вызов переменной функции без видимого прототипа (т. Е. Без объявления или с объявлением, в котором используются пустые скобки) имеет неопределенное поведение, начиная с C89/C90. Кроме того, вызов * любой * функции без видимого объявления (который может быть или не быть прототипом) является нарушением ограничения в C99 и более поздних версиях; C99 отказался от «неявного правила« int ». –

1

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

Ваша программа способна правильно подключиться к стандартной библиотеке и выполнить ее правильно.

"Hello World!" это очень простая программа, поэтому было бы ошибкой полагаться на это поведение на что-либо существенное.

+1

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

+1

Начиная с стандарта ISO ISO 1999 года, вызов функции без видимого объявления (вариативный или нет) является нарушением * ограничения *, требующим диагностики. В предыдущем стандарте 1989/1990 это не так. Многие компиляторы по умолчанию не соответствуют текущему стандарту. Соответствующий компилятор C99 или C11 должен, по крайней мере, выдать диагностику (возможно, нефатальное предупреждение) для кода в вопросе. –

Смежные вопросы