4

想出这个问题的标题有点麻烦。

我最近摸索到了 C 的世界。

我有一点代码,基本上显示了驱动器的容量和可用空间。它在我尝试过的几个不同的 Linux 发行版以及 Solaris 和 AIX 上运行良好。我最近在一个 HP-UX PA-RISC 机器上编译并得到(在我看来)一个非常奇怪的错误。

struct statfs   fsStat;
err = statfs(rootPath,&fsStat);
unsigned long long totalBytes = (unsigned long long)(fsStat.f_bsize * fsStat.f_blocks);

当我这样做时,在 GDB 中:

p (fsStat.f_bsize * fsStat.f_blocks)

结果是 1335205888 但是在运行计算之后,当我做

p totalByes

结果是 18446744071562067968

任何甚至可以让我知道在这里尝试什么的信息都会非常棒。曾经以为我知道如何编程,直到我开始做多平台 C :(

4

2 回答 2

6

假设:

乘法溢出,所以fsStat.f_bsize * fsStat.f_blocks产生了-2147483648的溢出结果。当它转换为 时unsigned long long,它产生 18446744071562067968,即 0xffffffff80000000,将 -2147483648 包装为 64 位无符号格式的结果。GDB 使用与 C 不同的算法,因此它显示了数学上正确的结果。

要解决此问题,请更改(unsigned long long) (fsStat.f_bsize * fsStat.f_blocks)(unsigned long long) fsStat.f_bsize * fsStat.f_blocks, 以在乘法之前转换为更宽的整数格式。

unsigned long long使用uint64_t(from <stdint.h>) 或平台提供的类型(一些 Linux 标头)来处理磁盘大小要好。

于 2013-08-08T18:18:40.637 回答
4

我的猜测是,f_bsize并且f_blocks是 type int。该值可能溢出为负值。

unsigned long long在将它们相乘之前尝试将这些值中的每一个转换为。

于 2013-08-08T18:17:01.147 回答