strtoull("-1", NULL, 0)
在我测试的系统(带有Apple Libc的OS / X,带有Glibc的Linux)上评估为18446744073709551615
,({0xFFFFFFFFFFFFFFFF
又名ULLONG_MAX
)。
既然strtoull
应该检查返回类型范围之外的值,为什么它不为所有负值返回0
?
编辑:-ULLONG_MAX
周围的行为也似乎不一致:
strtoul("-18446744073709551615", NULL, 0) -> 1, errno=0
strtoul("-18446744073709551616", NULL, 0) -> 18446744073709551615, errno=34
答案 0 :(得分:9)
C节标准(C99中的7.20.1.4节,C11中的7.22.1.4节,两者均第5段)的现行解释是,转换是在第一步中执行的,而忽略负号,产生未签名的结果。然后,该结果被否定。这是由
建议的标准文字中的如果主题序列以减号开头,则转换结果取反(返回类型)。
。 Negating values of unsigned type is well-defined,因此,如果第一步产生可表示的值,则总体结果可表示。由于没有,因此没有后续错误。
另一方面,如果输入字符串包含的数字太大,以致不能将其表示为unsigned long long int
值,则转换的第一步不能产生可表示的值,并且第8款适用:
如果正确的值超出可表示的值的范围,则返回[…]
ULLONG_MAX
,并将宏ERANGE
的值存储在errno
中。 / p>
同样,几乎所有实现者都以这样一种方式来解释标准:可表示值检查仅适用于第一步转换,从输入字符串中的任意精度非负整数到无符号类型。