gpt4 book ai didi

c - 如果 LONG_MAX 为 2147483647,strtol ("-2147483648", 0, 0) 是否溢出?

转载 作者:太空狗 更新时间:2023-10-29 14:59:09 27 4
gpt4 key购买 nike

根据 strtol 的规范:

If the subject sequence has the expected form and the value of base is 0, the sequence of characters starting with the first digit shall be interpreted as an integer constant. If the subject sequence has the expected form and the value of base is between 2 and 36, it shall be used as the base for conversion, ascribing to each letter its value as given above. If the subject sequence begins with a minus-sign, the value resulting from the conversion shall be negated. A pointer to the final string shall be stored in the object pointed to by endptr, provided that endptr is not a null pointer.

手头的问题是,在否定之前,该值不在 long 的范围内。例如,在 C89 中(整型常量不能取long long类型),写-2147483648可能是溢出;你必须写 (-2147483647-1) 或类似的。

由于使用“整数常量”的措辞可以解释为将 C 规则应用于整数常量的类型,这可能足以使我们免于此处的未定义行为,但同样的问题(没有这么容易解决)将应用于 strtoll

最后,请注意,即使确实溢出,也应该返回“正确”的值。所以这个问题实际上只是关于在这种情况下是否可以或必须设置 errno

最佳答案

虽然我今天无法指出标准中的特定措辞,但当我为 4BSD 编写 strtol 时早在 1990 年代,我就非常确定这应该设置errno,并确保我不会。这是基于标准中的措辞,还是与某人的个人讨论,我已记不清了。

为了避免溢出,这意味着必须非常小心地进行计算。我在 unsigned long 中完成了它并包含了这个注释(仍然在各种 BSD 的 libc 源代码中):

    /*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set 'any' if any `digits' consumed; make it negative to indicate
* overflow.
*/

我曾经(并且在某种程度上仍然)对 C 库中的此操作与语言本身的语法之间的不对称感到恼火(其中负数是两个单独的标记,- 紧随其后通过数字,所以写 -217483648 意味着 -(217483648) 变成 -(217483648U) 这当然是 217483648U 因此是肯定的!(当然假设 32 位 int;有问题的值因其他位大小而异。)

关于c - 如果 LONG_MAX 为 2147483647,strtol ("-2147483648", 0, 0) 是否溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17003270/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com