首页 文章

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

提问于
浏览
-1

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

函数: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的作用相同,但会将结果转换为无符号整数 . 这意味着例如strtoul在“-1”返回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 回答

  • 1

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

    是的,它有冲突 .

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

  • 3

    没有冲突 .

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

    unsigned 否定是明确定义的 .

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

    按照标准,"-2"应转换为 ULONG_MAX - 2 .

    所以也许"Function: unsigned long ... overflow"文本以某种方式与C规范冲突(特别是“输入比 LONG_MIN 返回 (ULONG_MAX + 1) / 2 更负)”,但 strtoul() 功能是正确的 .

相关问题