问题
The follows is the description of function strtoul
in stdlib.h
implemented by glibc:
Function: unsigned long int strtoul (const char *retrict string, char **restrict tailptr, int base) Preliminary: | MT-Safe locale | AS-Safe | AC-Safe | See POSIX Safety Concepts.
The strtoul (“string-to-unsigned-long”) function is like strtol except it converts to an unsigned long int value. The syntax is the same as described above for strtol. The value returned on overflow is ULONG_MAX (see Range of Type).
If string depicts a negative number, strtoul acts the same as strtol but casts the result to an unsigned integer. That means for example that strtoul on "-1" returns ULONG_MAX and an input more negative than LONG_MIN returns (ULONG_MAX + 1) / 2.
strtoul sets errno to EINVAL if base is out of range, or ERANGE on overflow.
It means that, for example, "-2"
will be converted to ULONG_MAX - 1
. But the C11 standard [7.22.1.4-8] says:
The strtol, strtoll, strtoul, and strtoull functions return the converted value, if any. If no conversion could be performed, zero is returned. If the correct value is outside the range of representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned (according to the return type and sign of the value, if any), and the value of the macro ERANGE is stored in errno.
So by the standard, for example, "-2"
shall be converted to ULONG_MAX
. Is it a conflict?
回答1:
This is probably another case of glibc
implementing a feature before standardization occurred.
Yes it conflicts.
However, I consider glibc's result more useful. If you need perfect compliance, you can wrap the function to perform the conversion.
回答2:
No conflict.
If the subject sequence begins with a minus sign, the value resulting from the conversion is negated (in the return type). C11dr §7.22.1.4 5
unsigned
negation is well defined.
A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type. §6.2.5 9
By the standard, "-2" shall be converted to ULONG_MAX - 2
.
So maybe "Function: unsigned long ... overflow" text conflicts with the C spec in some manner (specifically the "input more negative than LONG_MIN
returns (ULONG_MAX + 1) / 2
)", but strtoul()
functionality is correct.
来源:https://stackoverflow.com/questions/32895853/does-the-implementation-of-strtoul-in-glibc-conflicts-with-the-c11-standard