strtoull("-1", NULL, 0) 和其他负值的惊人行为
Surprising behavior of strtoull("-1", NULL, 0) and other negative values
strtoull("-1", NULL, 0)
在我测试的系统(OS/X with Apple Libc,Linux 与 Glibc).
既然 strtoull
应该检查超出 return 类型范围的值,为什么它不 return 0
检查所有负值?
编辑: -ULLONG_MAX
周围的行为似乎也不一致:
strtoul("-18446744073709551615", NULL, 0) -> 1, errno=0
strtoul("-18446744073709551616", NULL, 0) -> 18446744073709551615, errno=34
C 部分标准(C99 中的第 7.20.1.4 节,C11 中的第 7.22.1.4 节,两者的第 5 段)的普遍解释是转换是在第一步中执行的,忽略减号,产生一个未签名的结果。这个结果然后被否定。
建议
If the subject sequence begins with a minus sign, the value resulting from the conversion is negated (in the return type).
在标准文本中。 Negating values of unsigned type is well-defined,因此如果第一步产生可表示的值,则总体结果是可表示的。由于取反没有后续错误。
另一方面,如果输入字符串包含的数字太大以至于无法表示为 unsigned long long int
值,则转换的第一步无法生成可表示的值,并且段落8 个适用:
If the correct value is outside the range of representable values, […] ULLONG_MAX
is returned […], and the value of the macro ERANGE
is stored in errno
.
同样,几乎所有实施者都以这样一种方式解释标准,即可表示值检查仅适用于第一个转换步骤,从输入字符串中的任意精度非负整数到无符号类型。
strtoull("-1", NULL, 0)
在我测试的系统(OS/X with Apple Libc,Linux 与 Glibc).
既然 strtoull
应该检查超出 return 类型范围的值,为什么它不 return 0
检查所有负值?
编辑: -ULLONG_MAX
周围的行为似乎也不一致:
strtoul("-18446744073709551615", NULL, 0) -> 1, errno=0
strtoul("-18446744073709551616", NULL, 0) -> 18446744073709551615, errno=34
C 部分标准(C99 中的第 7.20.1.4 节,C11 中的第 7.22.1.4 节,两者的第 5 段)的普遍解释是转换是在第一步中执行的,忽略减号,产生一个未签名的结果。这个结果然后被否定。
建议If the subject sequence begins with a minus sign, the value resulting from the conversion is negated (in the return type).
在标准文本中。 Negating values of unsigned type is well-defined,因此如果第一步产生可表示的值,则总体结果是可表示的。由于取反没有后续错误。
另一方面,如果输入字符串包含的数字太大以至于无法表示为 unsigned long long int
值,则转换的第一步无法生成可表示的值,并且段落8 个适用:
If the correct value is outside the range of representable values, […]
ULLONG_MAX
is returned […], and the value of the macroERANGE
is stored inerrno
.
同样,几乎所有实施者都以这样一种方式解释标准,即可表示值检查仅适用于第一个转换步骤,从输入字符串中的任意精度非负整数到无符号类型。