glibc中strtoul的实现是否与C11标准冲突?

问题描述 投票:1回答:2

以下是由glibc实现的strtoul函数stdlib.h的描述:

函数:unsigned long int strtoul(const char * retrict string,char ** restrict tailptr,int base)初步:| MT-Safe区域设置| AS-Safe | AC-Safe |请参阅POSIX安全概念。

strtoul(“string-to-unsigned-long”)函数类似于strtol,除了它转换为unsigned long int值。语法与上面针对strtol所述的语法相同。溢出时返回的值为ULONG_MAX(请参阅类型范围)。

如果string描述了一个负数,则strtoul与strtol的作用相同,但会将结果转换为无符号整数。这意味着例如,“-1”上的strtoul返回ULONG_MAX,并且输入比LONG_MIN更负的输入返回(ULONG_MAX + 1)/ 2。

如果base超出范围,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。这是冲突吗?

c language-lawyer glibc c11
2个回答
2
投票

这可能是glibc在标准化发生之前实现功能的另一种情况。

是的,它有冲突。

但是,我认为glibc的结果更有用。如果您需要完美的合规性,可以包装该功能以执行转换。


3
投票

没有冲突。

如果主题序列以减号开头,则转换产生的值将被否定(在返回类型中)。 C11dr§7.22.1.45

unsigned否定是明确的。

涉及无符号操作数的计算永远不会溢出,因为无法通过生成的无符号整数类型表示的结果将以比结果类型可以表示的最大值大1的数量为模。 §6.2.59

按照标准,“ - 2”应转换为ULONG_MAX - 2

所以也许“函数:无符号长...溢出”文本以某种方式与C规范冲突(特别是“输入比LONG_MIN更负面返回(ULONG_MAX + 1) / 2)”,但strtoul()功能是正确的。

© www.soinside.com 2019 - 2024. All rights reserved.