Установка Incorrectly и использующий errno
Неправильное употребление errno происходит, когда вы проверяете errno
для состояния ошибки в ситуациях, где проверка errno
не гарантирует отсутствия ошибок. В некоторых случаях, проверка errno
может привести к ложным положительным сторонам.
Например, вы проверяете errno
следующие вызовы функций:
fopen
: Если вы следуете Стандарту ISO®, функциональная сила не установила errno
при ошибках.
atof
: Если вы следуете стандарту ISO, функция не устанавливает errno
.
signal
: errno
значение указывает на ошибку, только если функция возвращает SIG_ERR
ошибочный индикатор.
Стандарт ISO C не осуществляет это, эти функции устанавливают errno
при ошибках. Устанавливают ли функции errno
или не является зависящим от реализации.
Обнаружить ошибки, если вы проверяете errno
один, валидность этой проверки также становится зависящей от реализации.
В некоторых случаях, errno
значение указывает на ошибку, только если функция возвращает определенный ошибочный индикатор. Если вы проверяете errno
прежде, чем проверять функциональное возвращаемое значение, вы видите ложные положительные стороны.
Для получения информации о том, как обнаружить ошибки, см. документацию для той определенной функции.
Как правило, функции возвращают внеполосный ошибочный индикатор, чтобы указать на ошибки. Например:
fopen
возвращает нулевого указателя, если ошибка происходит.
signal
возвращает SIG_ERR
ошибочный индикатор и наборы errno
к положительному значению. Проверяйте errno
только после того, как вы проверяли функциональное возвращаемое значение.
errno
После fopen
Вызвать#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define fatal_error() abort()
const char *temp_filename = "/tmp/demo.txt";
FILE *func()
{
FILE *fileptr;
errno = 0;
fileptr = fopen(temp_filename, "w+b");
if (errno != 0) {
if (fileptr != NULL) {
(void)fclose(fileptr);
}
/* Handle error */
fatal_error();
}
return fileptr;
}
В этом примере, errno
первая переменная, которая проверяется после вызова fopen
. Вы можете ожидать тот fopen
изменения errno
к ненулевому значению, если ошибка происходит. Если при запуске этот код с реализацией fopen
это не устанавливает errno
при ошибках вы можете пропустить состояние ошибки. В этой ситуации, fopen
может возвратить нулевого указателя, который выходит из обнаружения.
fopen
После вызоваОдна возможная коррекция должна только проверять возвращаемое значение fopen
для нулевого указателя.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #define fatal_error() abort() const char *temp_filename = "/tmp/demo.txt"; FILE *func() { FILE *fileptr; fileptr = fopen(temp_filename, "w+b"); if (fileptr == NULL) { fatal_error(); } return fileptr; }
Errno, не проверяемый, происходит, когда вы вызываете функцию, которая устанавливает errno
указать на состояние ошибки, но не проверять errno
после вызова. Для этих функций, проверяя errno
единственный надежный путь состоит в том, чтобы определить, произошла ли ошибка.
Функции, которые устанавливают errno
при ошибках включайте:
fgetwc
, strtol
, и wcstol
.
Для всестороннего списка функций см. документацию о errno.
POSIX® errno
- установка функций, таких как encrypt
и setkey
.
Чтобы видеть если вызов функции, завершенный без ошибок, проверяйте errno
для ошибочных значений.
Возвращаемые значения их errno
- устанавливающие функции не указывают на ошибки. Возвращаемое значение может быть одним из следующего:
void
Даже если ошибка происходит, возвращаемое значение может совпасть со значением от успешного вызова. Такие возвращаемые значения называются внутриполосными ошибочными индикаторами.
Можно определить, произошла ли ошибка только путем проверки errno
.
Например, strtol
преобразует строку в длинное целое и возвращает целое число. Если результат переполнения преобразования, функция возвращает LONG_MAX
и наборы errno
к ERANGE
. Однако функция может также возвратить LONG_MAX
от успешного преобразования. Только путем проверки errno
можно ли различать ошибку и успешное преобразование.
Прежде, чем вызвать функцию, набор errno
обнулять.
После вызова функции, чтобы видеть, произошла ли ошибка, сравнивают errno
обнулять. В качестве альтернативы сравните errno
к известным ошибочным значениям индикатора. Например, strtol
наборы errno
к ERANGE
указать на ошибки.
Сообщение об ошибке в результате Polyspace® показывает ошибочное значение индикатора, что можно выдержать сравнение с.
errno
Не проверенный после вызова strtol
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
int main(int argc, char *argv[]) {
char *str, *endptr;
int base;
str = argv[1];
base = 10;
long val = strtol(str, &endptr, base);
printf("Return value of strtol() = %ld\n", val);
}
Вы используете возвращаемое значение strtol
не проверяя errno
.
errno
После вызоваПрежде, чем вызвать strtol
, установите errno
обнулять. После вызова strtol
, проверяйте возвращаемое значение на LONG_MIN
или LONG_MAX
и errno
для ERANGE
.
#include<stdlib.h> #include<stdio.h> #include<errno.h> #include<limits.h> int main(int argc, char *argv[]) { char *str, *endptr; int base; str = argv[1]; base = 10; errno = 0; long val = strtol(str, &endptr, base); if((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE) { printf("strtol error"); exit(EXIT_FAILURE); } printf("Return value of strtol() = %ld\n", val); }
Errno не сбрасывают, происходит, когда вы не сбрасываете errno
прежде, чем вызвать функцию, которая устанавливает errno
указать на состояние ошибки. Однако вы проверяете errno
для того состояния ошибки после вызова функции.
errno
не является чистым и может содержать значения от предыдущего вызова. Проверка errno
поскольку ошибки могут произвести ложное впечатление, что ошибка произошла.
errno
обнуляется при запуске программы, но впоследствии, errno
не сбрасывается стандартной библиотечной функцией C. Необходимо явным образом установить errno
обнулять при необходимости.
Прежде, чем вызвать функцию, которая устанавливает errno
чтобы указать на состояние ошибки, сбросьте errno
обнулять явным образом.
errno
Не сброс перед вызовом strtod
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>
#define fatal_error() abort()
double func(const char *s1, const char *s2)
{
double f1;
f1 = strtod (s1, NULL);
if (0 == errno) {
double f2 = strtod (s2, NULL);
if (0 == errno) {
long double result = (long double)f1 + f2;
if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX))
{
return (double)result;
}
}
}
fatal_error();
return 0.0;
}
В этом примере, errno
не сбрасывается к 0 перед первым вызовом strtod
. Проверка errno
для 0 позже может привести к положительной лжи.
errno
Перед вызовомОдна возможная коррекция должна сбросить errno
к 0 прежде, чем вызвать strtod
.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <float.h> #define fatal_error() abort() double func(const char *s1, const char *s2) { double f1; errno = 0; f1 = strtod (s1, NULL); if (0 == errno) { double f2 = strtod (s2, NULL); if (0 == errno) { long double result = (long double)f1 + f2; if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX)) { return (double)result; } } } fatal_error(); return 0.0; }
Разрешимость: неразрешимый |
[1] Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.