2013-10-14 53 views
13

是否有一個標準類型(或MSVC專有)typedef,用於包含size_t值的全部範圍的簽名類型?即在64位系統上,它將是一個128位有符號整數。typedef是否可以包含size_t的簽名類型?

+0

'unsigned long long' –

+0

哎呀錯字標題。我問的是簽名類型。 – japreiss

+0

如果你想要一個簽名類型的原因是爲了重載/以特殊含義轉義它,你可以考慮'boost :: optional <>'包裝器。 –

回答

10

通常不可能定義這種類型。對於實現來說,使size_t成爲最大的受支持的無符號類型是完全合法的,這意味着沒有簽名類型可以保存其所有值。

ptrdiff_t不一定夠寬。這是減去兩個指針的結果,但沒有任何說明指針減法不能溢出。見第5.7節C++標準的:

當兩個指針相同的數組對象的元素相減, 的結果是兩個陣列 元素的下標之差。結果的類型是實現定義的有符號整數類型 ;此類型應與 std::ptrdiff_t<cstddef>表頭(18.2)中定義的類型相同。與其他 算術溢出一樣,如果結果不符合提供的空間,則 的行爲是未定義的。

最大的符號的類型是intmax_t,在<stdint.h><cstdint>定義。這是一個C99特性,而C++ 11是第一個包含C99標準庫的C++標準,所以你的編譯器可能不支持它(而MSVC很可能不支持它)。如果有符號類型寬度足以容納size_t類型的所有可能值,則intmax_t是(儘管可能是是也是合格的較窄符號類型)。

您也可以使用long long,這是一種保證至少爲64位的符號類型(最有可能與intmax_t相同)。即使它不足以容納size_t類型的所有可能值,它幾乎肯定會保留所有相關的值類型size_t - 除非您的實現實際支持大於8 EB(8192 PB或8388608 TB)的對象。

(注意,我使用的「exa-」,「peta-」和「tera-」二進制的定義,這是有問題的有效性。)

+1

*「和MSVC最有可能不會」* - 作爲一個方面說明,新的整數類型確實是* MSVC *標準庫自2010 *以來的少數C++ 11功能之一。 –

+0

此外,如果您不確定在給定平臺上可以獲得多大的尺寸,請添加一個:static_assert(sizeof(intmax_t)> sizeof(size_t),「無法獲得保證尺寸爲size_t的簽名類型「);'所以編譯器會警告你,如果你有可能陷入困境。 –

2

我認爲你需要這種類型的一些一種指針算術。這是不太可能的,你需要任何東西比std::ptrdiff_t。唯一的情況是,這將在現代機器上扮演一個角色,當你處於32位模式並且你正在處理一個數據集超過2^31字節時。 (在沒有特殊工作的情況下,這在Windows上是不可能的。)您將無法同時使用兩個這種大小的數組。在這種情況下,無論如何你都應該在64位模式下工作。

在64位模式下,隨着內存開發速度的提升,在接下來的40年左右時間內,它很可能不會成爲問題。當它成爲一個問題時,然後在128位模式下編譯你的代碼,它將繼續運行。 ;)

2

如果您想要一個可以包含系統最大值的標準類型,可能需要<cstdint>(因爲C++ 11)可以提供幫助。

該頭文件中有一個typedef,它包含最大寬度整數類型,類型爲intmax_t。有符號整數的intmax_t和無符號整數的uintmax_t是該體系結構完全支持的最大整數。

所以,讓我們假設你是在64位架構,下面的指令:

std::cout << "intmax_t is same int64_t? " 
      << (std::is_same<intmax_t, int64_t>::value ? "Yes" : "No"); 

將輸出:

還會將intmax_t是相同的int64_t?是

Live demo

希望它有幫助。

相關問題