Gcc

為什麼 stat.st_size 的類型不是 unsigned int?

  • November 23, 2020

我試圖依靠stat(2)系統呼叫來確定文件的大小,以便為其分配適當的緩衝區。更具體地說,我使用的stat.st_size是系統呼叫填充的結構。

但是在調試過程中,我注意到一個足夠大的文件會引起一些麻煩:struct stat手冊頁中定義的文件如下所示:

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

Wherest_size被定義為off_t解析為 along int並且令我驚訝的是,而不是unsigned long int. 這當然會導致一個問題,即足夠大的文件溢出整數並導致該值表示負數,我在檢查中沒有考慮到(為什麼會st_size是負數?)

此外,根據手冊頁,EOVERFLOW當塊數無法表示時,系統呼叫應返回錯誤off_t,但在我的本地 ubuntu 中使用 gcc 9.3 - 大小大於0x80000000字節的文件不會引發此類錯誤。此外,“正確”的方法是編譯-D_FILE_OFFSET_BITS=64off_t欄位從 32 位整數擴展為 64 位整數,這可以幫助您管理更大的文件。

這當然解決了我的問題,但我仍然想知道,為什麼將定義保留為有符號整數?

off_tPOSIX 定義,並且是

用於文件大小。

它需要能夠表示負值,因為它不僅用於文件大小,還用於文件偏移量(因此得名),並且偏移量可以是負數(lseek例如,在文件中移回)。

您可能想知道為什麼size_t不能使用它來代替;但這用於測量對象的大小,尤其是 C 對象的大小,而不是文件大小。

引用自:https://unix.stackexchange.com/questions/621157