Что я могу предположить о поведении atoi () по ошибке?

стандартная функция библиотеки C atoi задокументировано в ISO 9899: 2011 как:

7.22.1 функции числового преобразования

1 функции atof, atoi, atol и atoll Не нужно влиять на значение целочисленного выражения errno на ошибку. Если значение результата не может быть представлено, поведение не определено.

...

7.22.1.2 в atoi, atol и atoll функции

справка

#include <stdlib.h>
int atoi(const char *nptr);
long int atol(const char *nptr);
long long int atoll(const char *nptr);

описание

2 к atoi, atol и atoll функции преобразуют начальную часть строки, на которую указывает nptr to int, long int и long long int представительства соответственно. За исключением поведения при ошибке, они эквивалентны

atoi: (int)strtol(nptr, (char **)NULL, 10)
atol: strtol(nptr, (char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)

возвращает

3 к atoi, atol и atoll функции возвращают преобразованный значение.

каково предполагаемое поведение, когда строка указывает на nptr невозможно разобрать как целое число? По-видимому, существуют следующие четыре мнения:--26-->

  • преобразование не выполняется и возвращается ноль. Это документация, представленная некоторыми ссылками, такими как этот.
  • поведение похоже на strtol кроме этого errno не может быть установлен. Это вытекает из принятия "за исключением поведения при ошибке" как ссылка на §7.22.1 ¶1.
  • поведение не определено. Это в POSIX:

    вызов atoi (str) должен быть эквивалентен:

    (int) strtol(str, (char **)NULL, 10)
    

    за исключением того, что обработка ошибок может отличаться. Если значение не может быть представлено, поведение не определено.

    кроме того, секция Использование Приложения гласит:

    функция atoi() входит в strtol (), но сохраняется, поскольку широко используется в существующем коде. Если известно, что число не находится в диапазоне, следует использовать strtol (), поскольку atoi () не требуется для проверки ошибок.

    обратите внимание, что POSIX утверждает, что спецификация выровнена по ISO 9899:1999 (который содержит тот же язык, что и ISO 9899: 2011, насколько мне известно):

    функциональность, описанная на этой справочной странице, выровнена с Стандарт ISO на C. Любой конфликт между описанными здесь требованиями и стандартом ISO C является непреднамеренным. Этот том POSIX.1-2008 переносится на стандарт ISO C.

    согласно моему местному члену комитета POSIX, это историческое поведение UNIX.

  • поведение неопределено. Эта интерпретация возникает потому, что §7.22.1.2 ¶2 никогда явно не говорит, что происходит при ошибке. Поведение, которое ни определено, ни явно реализация, определенная или неуказанная, не определена.

какая из этих интерпретаций правильная? Пожалуйста, попробуйте обратиться к авторитетной документации.

1 ответов


каково предполагаемое поведение, когда строка указывает на nptr не может быть проанализировано как целое число?

чтобы быть ясным, этот вопрос относится к

// Case 1
value = atoi("");
value = atoi("  ");
value = atoi("wxyz");

и не следующее:

// Case 2
// NULL does not point to a string
value = atoi(NULL);
// Convert the initial portion, yet has following junk
value = atoi("123xyz");
value = atoi("123 ");

и, возможно, / возможно, не следующее В зависимости от использования целое.

// Case 3
// Can be parsed as an _integer_, yet overflows an `int`.
value = atoi("12345678901234567890123456789012345678901234567890");

поведение "Non-Case 2"ato*() зависит от значения in

на atoi, atol и atoll функции преобразуют начальную часть строки, на которую указывает nptr to int, long int и long long int представительства соответственно. За исключением поведения на , они эквивалентны
atoi: (int)strtol(nptr, (char **)NULL, 10)
...
C11dr §7.22.1.2 2


конечно включает случай 3: "Если правильное значение находится вне диапазона представимые значения". strto*(), хотя, может быть, и нет ato*() в этом случае выберите определена в <errno.h>. Так как спецификация ato*() не относится к этому , переполнение, результат, является UB per

неопределенное поведение в противном случае указывается в этом международном стандарте словами ‘неопределенное поведение’ или отсутствием какого-либо явного определения поведения. C11dr §4 2


для случая 1, поведение strto*() четко определен и не указан, чтобы повлиять errno. Спецификация вдается в детали (§7.22.1.4 4) и называет эти "нет преобразования", а не . Таким образом, он может утверждать случай 1 strto*() поведение не является , но "без преобразования". Таким образом, за ...

"если преобразование не может быть выполнено, возвращается нуль. C11dr §7.22.1.4 8

... atoi("") должна возвращать 0.