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

时间:2015-10-01 19:59:17

标签: c language-lawyer glibc c11

以下是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(请参阅类型范围)。

     

如果字符串描绘了一个负数,则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。这是冲突吗?

2 个答案:

答案 0 :(得分:3)

没有冲突。

  

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

unsigned否定定义明确。

  

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

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

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

答案 1 :(得分:2)

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

是的,它有冲突。

但是,我认为glibc的结果更有用。如果您需要完美的合规性,可以将函数包装起来执行转换。