Подтвердить что ты не робот

Всегда ли stdio задает errno?

Когда поток stdio встречает ошибку (но не EOF), индикатор ошибки потока будет установлен таким образом, что ferror() будет возвращать ненулевое значение. Я всегда предполагал, что в errno имеется больше информации. Но откуда я это знаю?

Документация для некоторых функций [. man fopen под Linux] говорит, что errno также будет установлен. Однако man fgets вообще не упоминает errno. Информационные страницы glibc обнадеживают:

В дополнение к установке индикатора ошибки, связанного с поток, функции, которые работают с потоками, также устанавливают `errno 'в так же, как соответствующие низкоуровневые функции, которые работают с файлом дескрипторы.

Но я не знаю, насколько сильна эта гарантия. Требуется ли это по стандарту C? Что происходит в Visual C/С++?

4b9b3361

Ответ 1

Сам стандарт C не требует особого использования функций errno WRT для stdio; он указывает ferror(), но говорит только об этом

7.13.10.3 Функция ferror Функция ferror проверяет индикатор ошибки для потока, на который указывает поток. Функция ferror возвращает ненулевое значение тогда и только тогда, когда для потока установлен индикатор ошибки.

из проекта C99: http://www.vmunix.com/~gabor/c/draft.html. Любые фактические коды ошибок используются, по большей части, для реализации.

Однако библиотека GNU C на linux также соответствует спецификациям POSIX:

http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm

которые в этом контексте более четко определены. Например, если вы посмотрите на страницу fopen:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html

В разделе "Ошибки" вы увидите много подробной информации, включая конкретные коды errno.

Опять же, библиотека GNU C, используемая практически во всех нормальных Linux-системах, совместима с POSIX, поэтому вы можете рассчитывать на эту информацию;). Те (онлайн) страницы руководства POSIX также, как правило, более подробные, чем стандартные страницы руководства системы Linux (читайте оба).

WRT для операций с файлами на других (не-POSIX) платформах, они будут иметь свои собственные реализации. К сожалению, такие вещи не прозрачно переносятся в стандартном C. В потоках С++ есть более стандартизованная обработка ошибок.

Ответ 2

В соответствии со стандартом C11, глава 7.21 ( "stdio.h" ), только fgetpos, fsetpos и ftell записываются в errno в случае ошибки.