Могу ли я когда-нибудь предположить, что функция C stdlib не использует errno? - PullRequest
4 голосов
/ 08 декабря 2010

Я смотрю на фрагмент кода C, который выглядит следующим образом:

void printerror(char *message)
{
    printf ("There was an error: '%s'\n", message);
    switch (errno) {
       ... do stuff depending on errno
    }
}

Я думаю, что это может быть проблемой, потому что printf может измениться из-за ошибки при входе в функцию и достижении switch.Тем не менее, на странице руководства printf ничего не говорится о настройке errno, так что я могу предположить, что она никогда не установит это?Есть ли в стандартах что-то, что гарантирует, какие функции будут и не будут использоваться errno?

Ответы [ 3 ]

10 голосов
/ 08 декабря 2010

Любая функция может устанавливать errno, но только если она устанавливает ненулевое значение. Спецификация ANSI C гласит:

Значение errno равно нулю при запуске программы, но никогда не устанавливается на ноль любой библиотечной функцией. * Значение errno может быть установлено в отличным от нуля при вызове библиотечной функции, независимо от того, есть ли ошибка, при условии, что использование errno не задокументировано в описании функция в стандарте.

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

Итак, если вы используете errno, наилучший подход состоит в том, чтобы установить значение 0 непосредственно перед вызовом библиотеки, который может завершиться ошибкой, и прочитать его сразу после. В приведенном выше случае было бы достаточно добавить что-то вроде:

int localErrno = errno

непосредственно перед оператором printf и используйте localErrno для вашего ключа. Это, конечно, предполагает, что нет никаких библиотечных вызовов между ошибочной функцией и вашим вызовом к printerror. Если есть, вам нужно будет сохранить errno после неудачного вызова и передать его в вашу функцию printerror.

4 голосов
/ 08 декабря 2010

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

3 голосов
/ 08 декабря 2010

Стандарт C99 определяет следующее:

Значение errno равно нулю при запуске программы, но никогда не устанавливается равным нулю какой-либо библиотечной функцией. Значение errno может быть установлено в ненулевое значение при вызове библиотечной функции независимо от того, есть ли ошибка, при условии, что использование errno не задокументировано в описании функции в этом международном стандарте.

Итак, вкратце, errno может быть установлено с помощью любой библиотечной функции. Чтобы определить, действительно ли это в данном случае, стандартная практика состоит в том, чтобы установить его на ноль перед вызовом рассматриваемой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...