Does the implementation of strtoul in glibc conflicts with the C11 standard?

岁酱吖の 提交于 2019-12-11 09:50:50

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!