Ниже приводится описание функции strtoul
в stdlib.h
, реализованной glibc:
Функция: unsigned long int strtoul (const char * retrict string, char ** restrict tailptr, int base) Предварительно: | Региональный стандарт MT-Safe | AS-Safe | AC-Safe | См. Концепции безопасности POSIX.
Функция strtoul («строка-в-беззнаковый-длинный») похожа на strtol, за исключением того, что она преобразуется в значение типа unsigned long int. Синтаксис такой же, как описано выше для strtol. Значение, возвращаемое при переполнении, - ULONG_MAX (см. «Диапазон типов»).
Если строка представляет собой отрицательное число, strtoul действует так же, как strtol, но преобразует результат в целое число без знака. Это означает, например, что strtoul на «-1» возвращает ULONG_MAX, а ввод более отрицательный, чем возвращает LONG_MIN (ULONG_MAX + 1) / 2.
strtoul устанавливает для errno значение EINVAL, если база вне допустимого диапазона, или ERANGE при переполнении.
Это означает, что, например, "-2"
будет преобразовано в ULONG_MAX - 1
. Но стандарт C11 [7.22.1.4-8] говорит:
Функции strtol, strtoll, strtoul и strtoull возвращают преобразованное значение, если оно есть. Если преобразование не может быть выполнено, возвращается ноль. Если правильное значение выходит за пределы диапазона представимых значений, возвращается LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX или ULLONG_MAX (в соответствии с типом возвращаемого значения и знаком значения, если таковые имеются), и значение макроса ERANGE сохраняется в errno.
Так, например, по стандарту "-2"
должен быть преобразован в ULONG_MAX
. Это конфликт?