为什么stat.st_size的类型不是unsigned int?

为什么stat.st_size的类型不是unsigned int?

我试图依靠stat(2)系统调用来确定文件的大小,以便为其分配适当的缓冲区。更具体地说,我使用的是stat.st_size系统调用填充的结构。

但在调试过程中,我注意到足够大的文件会引起一些麻烦:struct stat手册页中定义的内容如下所示:

struct stat {
    // ... 
    off_t     st_size;    /* total size, in bytes */
    // ... 
};

wherest_size被定义为off_twhich 解析为 a long int,令我惊讶的是,而不是unsigned long int.这当然会导致一个问题,即足够大的文件会溢出整数并导致该值表示负数,而我在检查中没有考虑到这一点(为什么会st_size是负数?)

另外,根据手册页,EOVERFLOW当块数无法在 中表示时,系统调用应该返回错误off_t,但在我使用 gcc 9.3 的本地 ubuntu 中 - 大小大于0x80000000字节的文件不会引发此类错误。此外,“正确”的方法是进行编译,-D_FILE_OFFSET_BITS=64off_t字段从 32 位整数扩展为 64 位整数,这可以帮助您管理更大的文件。

这当然解决了我的问题,但我仍然想知道,为什么将定义保留为有符号整数?

答案1

off_t由 POSIX 定义, 并且是

用于文件大小。

它需要能够表示负值,因为它不仅用于文件大小,还用于文件偏移量(因此得名),并且偏移量可以为负数(在文件中向后移动)lseek例如)。

您可能想知道为什么size_t不能用它来代替;但它用于测量对象的大小,特别是 C 对象,而不是文件大小。

相关内容