2013-07-15 25 views
0

假設我正在寫一個函數,它需要一個float a[]和一個偏移量到這個數組中,並返回該偏移量處的元素。是否合理使用簽名將off_t用於非字節偏移量是否合適?

float foo(float* a, off_t offset); 

對嗎?或者是off_t只與字節的偏移有關,而不是指針運算的元素大小?即當off_t類型的偏移量時,說a[offset]是否合理?

GNU C庫參考手冊說:

off_t 
    This is a signed integer type used to represent file sizes. 

,但並沒有告訴我很多。因爲在[offset]中使用的實際地址是+ sizeof(float)* offset的地址,所以「sizeof(float)* offset」是off_t ,並且sizeof(float)是size_t,並且它們都是具有'維度'的常量。

注:偏移量可能爲負。

+0

很確定訪問指針的負偏移被認爲是惡意的。 – zneak

+0

@zneak:也許,我不打算,但'a [-1]'是完全有效的代碼。 – einpoklum

+0

@zneak一點也不。爲什麼要這樣。 –

回答

0

也許答案是使用ptrdiff_t?它...

  • 可以是負值;
  • 暗指差異不是以字節爲單位,而是以任意大小爲單位,取決於元素類型。

您怎麼看?

+0

雖然其他人在我之後建議了'ptrdiff_t',但他們都發表了我不完全同意的說法。對不起大家。 – einpoklum

2

您可以使用size_tptrdiff_t作爲索引的類型(您的第二個參數更多的是float數組內的索引而不是偏移量)。

您的用途是一個索引,而不是偏移量。請注意,標準的offsetof宏被定義爲返回字節偏移量!

實際上,你甚至可以使用intunsigned,除非你相信你的陣列可能有數十億個組件。

你可能想要#include <stdint.h>(或<cstdint>與最近的C++),並已爲您的索引顯式大小爲int32_t

對於源可讀性的原因,您可以定義

typedef unsigned index_t; 

並在以後使用它,例如

float foo(float a[], index_t i); 

我的看法是,你只應該使用int爲您的索引類型。 (但適當地處理出界索引)。

+0

定義'index_t'類型常見嗎?另外,如果我想要一個可能有負面影響的偏移量呢? – einpoklum

+0

這並不常見,但人們通常只是使用'int' ... –

+0

他不能使用'size_t',因爲偏移量可能是負數。在內存中,正確的類型是'ptrdiff_t',或者如果輸入值的域或驗證確保溢出不能存在,則使用'int'。 –

1

我會說這是不恰當的,因爲

  1. off_t是(旨在)用於表示文件大小
  2. off_t是一個符號類型。

我會去size_type(通常是一個「類型定義」埃德爲size_t名),這是由STD容器中使用的。

+1

'std :: vector :: size_type'是'size_t'的一個typedef(它存在於C中)。 'size_type'不作爲獨立的類型存在。 – zneak

+0

但是,off_t如何表示文件大小?偏移量不是大小...偏移可能是負值,而大小不能。 – einpoklum

+0

@einpoklum,它與文件操作一起使用,如'fseek' /'lseek'。另一方面,'size_t'被定義爲能夠保持平臺上任何陣列的最大尺寸。聽起來更像你要找的東西。 – zneak

2

有沒有什麼好的理由說明你爲什麼不使用int?這是C++中整數值的默認類型 ,應該使用 ,除非有充分理由不這樣做。

當然,一個很好的理由可能是它可能溢出。如果 的上下文是這樣的,您可能會得到非常大的數組,那麼您可能需要使用ptrdiff_t,它被定義(在 C和C++中)作爲減去兩個 指針產生的類型:換句話說,它確保不會溢出(當 用作偏移量)時,對於大於1的所有類型。

+0

你能引用一些官方消息來源,建議應該使用「int」,除非有充分的理由不要「?我不想嘲笑你,我想閱讀理由。 – einpoklum

+0

@einpoklum「官方」來源是標準:在§3.9.1/ 2中, 純'int'是自然類型,其他是「提供給 滿足特殊需求」。實際上,使用任何類型的其他 都比'int'說有特殊需要。或許 額外的範圍,或節省空間。或者你需要模數運算的無符號類型,或者正在進行位操作。 (使用無符號類型通常清楚地表明您 不處理算術數據。) –

相關問題