Каково возвращаемое значение функции feof() в закрытом файле?

#c #file

Вопрос:

для потока ФАЙЛА*, если я прочитаю как можно больше данных, feof(поток) вернет мне ненулевое значение. Затем, если я закрою поток, он(поток) будет продолжать возвращать мне ненулевое значение? Это ГАРАНТИРОВАНО?

Ответ №1:

Вызов feof() в закрытом файле бессмыслен (на самом деле хуже, чем бессмыслен — он не определен, поэтому может произойти все, что угодно).

Из стандарта C:

Значение указателя на файловый объект не определено после закрытия связанного файла (включая стандартные текстовые потоки).

и

Успешный вызов функции fclose приводит к сбросу потока, на который указывает поток, и закрытию связанного файла. Любые неписаные буферизованные данные для потока доставляются в среду хоста для записи в файл; любые непрочитанные буферизованные данные удаляются. Независимо от того, выполняется вызов или нет, поток отсоединяется от файла, и любой буфер, установленный функцией setbuf или setvbuf, отсоединяется от потока (и освобождается, если он был выделен автоматически).

Ответ №2:

В зависимости от реализации библиотеки вызов fclose() приведет к освобождению ресурсов в файловой структуре, и последующие попытки вполне могут привести к сбою. Я считаю, что стандартным термином для этого является «неопределенное поведение».

Ответ №3:

Не делай этого. Не пытайтесь работать feof() с закрытым файлом. Результат не определен. Следите за тем, какие дескрипторы файлов закрыты каким-либо другим способом, вместо того, чтобы предполагать, что на них будет отображаться EOF.

В общем, неопределенного поведения в C следует избегать при написании переносимого кода… он может сделать что-то разумное на вашей платформе, но может сделать что-то совершенно нелепое или неожиданное на другой.

Люди из группы Usenet comp.lang.c много лет назад придумали гипотетический компьютер DeathStation 9000, который демонстрирует самое пугающе плохое поведение в случае неопределенных конструкций. Это своего рода обучающий инструмент, чтобы отпугнуть вас от того, чтобы полагаться на неопределенное поведение в C 🙂

Ответ №4:

Не для каждой реализации feof().

На самом деле, вы даже не можете гарантировать, что любой вызов f* будет работать после того, как вы позвоните в fclose.