2011-10-31 90 views
8

起初人們可能會認爲std::numeric_limits<size_t>::max(),但是如果有一個巨大的物體,它是否仍然可以提供一個最後一個指針?我猜不會。這是否意味着sizeof(T)可能產生的最大價值是std::numeric_limits<size_t>::max()-1?我是對的,還是我錯過了什麼?(T)可以產生的最大值大小是多少?

+0

對象*是否需要*提供一個過去的末尾指針? – Dabbler

+0

@Dabbler:根據C++標準,是的,因爲就指針算術而言,一個對象可以被看作一個大小爲1的數組。如果你願意的話,我可以查找確切的寫法。 – fredoverflow

+0

@Mike:錯誤,5.7§1說'爲了這些運算符的目的,指向非數組對象的指針的行爲與指向第一個長度爲1的數組的第一個元素的指針相同,該對象的類型作爲其元素type'。 – fredoverflow

回答

3

問:(T)可以產生的最大值大小是多少?

答:std::numeric_limits<size_t>::max()

顯然的sizeof不能超過std::numeric_limits<size_t>::max()返回一個值較大,因爲它不適合。唯一的問題是,它可以返回...::max()

是的。這是一個有效的程序,它違反了C++ 03標準的約束,它證明了一個例證。特別是,該程序不違反第5.3.3節[expr.sizeof]列出的任何約束,也不在§8.3.4[dcl.array]:

#include <limits> 
#include <iostream> 
int main() { 
typedef char T[std::numeric_limits<size_t>::max()]; 
std::cout << sizeof(T)<<"\n"; 
} 
+0

您是否真的完全讀過這個問題?弗雷德討論了他爲什麼認爲這可能是錯誤的。你怎麼能在問題出現後10分鐘以內提出一個與他的疑惑相矛盾的答案,甚至不用爭論他們呢? – sbi

+0

+1,但問題仍然是一次性結束指針所具有的價值。 – Dabbler

+0

嗯,在我的電腦上打印'4294967295',所以我想我錯了。 – fredoverflow

0

如果這是一個測試,我說(size_t) -1

+2

這就是'std :: numeric_limits :: max()'。 –

0

sizeof()表達式產生size_t類型的值。從C99標準6.5.3.4:

的結果的值是實現定義的,並且其類型( 無符號整型)是爲size_t,在STDDEF.H(和其他 頭)限定。

因此,sizeof()可以產生的最大值是SIZE_MAX。

+2

這是可以存儲在'size_t'中的最大值。這並不意味着'sizeof'使用'size_t'的所有值。 –

2

它不完全明確。但留在標準的安全範圍內,最大對象大小是std::numeric_limits<ptrdiff_t>::max()

那是因爲當你減去兩個指針,你會得到一個ptrdiff_t

這是一個有符號整數類型

歡呼&心連心,

+2

不幸的是,你可以有一個大於'std :: numeric_limits :: max()'的數組。如果你減去這個數組中相距太遠的兩個指針,那麼行爲是不確定的,參見[expr.add]/6。 – avakar

+0

@avakar:我會死的!很好的發現。 '和其他任何算術溢出一樣,如果結果不符合提供的空間,則行爲不確定。' – fredoverflow

3

如果std::numeric_limits<ptrdiff_t>::max() > std::numeric_limits<size_t>::max()您可以通過從一個過去末尾指針中減去指向它的指針來計算大小爲std::numeric_limits<size_t>::max()的對象的大小。

如果sizeof(T*) > sizeof(size_t)您可以有足夠的不同指針來解決該對象內的每個單個字節(例如,如果您有一個char數組),加上一個用於一個過去的結尾。

因此,有可能編寫一個實現,其中sizeof可以返回std::numeric_limits<size_t>::max(),並且您可以在其中指向一個大對象的一個​​末尾。

+1

如果實現的目標是具有分段地址的平臺,則sizeof(T *)> sizeof(size_t)'很容易是真實的。 –

+0

「我懷疑是否有這樣的實現[sizeof'可以返回'std :: numeric_limits :: max()']」。 g ++就是這樣的一個實現。 –

0

您可以使用符合標準的編譯器,該編譯器允許導致指針算術溢出的對象大小;但是,結果是不確定的。從C++標準中,5.7 [expr。添加]:

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

1

要求能夠指向超出數組的末尾與size_t的範圍無關。給定一個對象x,即使分隔兩個指針的字節數不能用size_t表示,(&x)+1也很可能是有效的指針。

你可以爭辯說,要求確實意味着指針的最大範圍的對象大小的上限減去對象的對齊。但是,我不相信這個標準在任何地方都說這種類型不能被定義;實例化它並且仍然保持一致是不可能的。

相關問題