gpt4 book ai didi

c、strtoul() 在发生错误/溢出时返回无效值

转载 作者:行者123 更新时间:2023-11-30 18:35:01 26 4
gpt4 key购买 nike

例如:

int main()
{
errno = 0;
printf("val = %lu err: %d\n", strtoul("12345678901234", NULL, 10), errno);
}

输出:

val = 1942892530 错误:0

手册页说 strtoul() 对于溢出值应该返回 ULONG_MAX (4294967295UL),有人可以解释一下 strtoul() 在这种情况下不返回 ULONG_MAX 的原因吗?

最佳答案

如果您使用的系统中 unsigned long 使用 64 位,而 int 仅使用 32 位,并且您未能包含 stdlib.h,编译器将假定: strtoul 是一个返回 int 值的函数。

在这种情况下,strtoul("12345678901234", NULL, 10) 将返回 12345678901234L 或十六进制 0xb3a73ce2ff2。由于假定该函数返回 int,因此它会转换为 32 位 int。这种转换是实现定义的,常见的实现仅保留 32 个低位,这将在此处给出 0x73ce2ff2 或十进制的 1942892530。您传递的是 32 位 int,而预期的是 64 位 int,因此结果是未定义的,但常见的实现只是使用堆栈中的下一个值来完成该值。因为我假设您的实现是小端,并且下一个值是 0,因为 errno 在上一行中设置为 0,并且参数的评估顺序未定义,所以您仍然获得 1942892530 作为无符号长整型。堆栈中的下一个值也恰好是 0。

TL/DR:由于您没有包含 stdlib.h 并忽略了编译器警告,编译器假定 strtoul 应返回 int 。此外,标准未明确规定函数参数的评估顺序。从那时起,您调用未定义的行为,并且所有内容都可以被打印。

你应该从中学到什么:

  • 不要忽略编译器警告
  • 不要忘记包含您使用的标准库的所有函数的 header

关于c、strtoul() 在发生错误/溢出时返回无效值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48602215/

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