c:仅在HP-UX上为unsigned long long分配了错误的值

时间:2013-08-08 18:08:04

标签: c hp-ux

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

我最近偶然发现了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 :(

2 个答案:

答案 0 :(得分:6)

假设:

乘法溢出,因此fsStat.f_bsize * fsStat.f_blocks产生溢出结果-2147483648。当它被转换为unsigned long long时,它产生了18446744071562067968,即0xffffffff80000000,这是以64位无符号格式包装-2147483648的结果。 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(来自<stdint.h>)或平台提供的类型(某些Linux标头)来处理磁盘大小。

答案 1 :(得分:4)

我的猜测是f_bsizef_blocks的类型为int。该值可能溢出为负值。

尝试将这些值中的每一个投放到unsigned long long,然后再相乘。