2016-01-29 33 views
2

我知道這個問題可能有很多不同的方式,但我加入我自己的,因爲這仍然不清楚。參考 - sizeof是否會返回真實的內存大小?

考慮以下代碼:

long double q = 1.2; 
long double &p = q; 
cout << sizeof(p) << endl;` 

long double是我的機器上的12個字節,並且代碼的輸出作爲預期12,因爲作爲標準表示:

當施加到基準或引用類型,結果是引用類型的大小爲 。 (ISO C++ $ 5.3.3/2)

但你最有可能都知道,參考實現是免費的,因此,作爲標準又說:

它是不確定是否不參考需要存儲(3.7)。

如此看來,明天我可以拿出我自己的參考實現,它需要200個字節,並確保該sizeof運算符返回正確的對象大小(而不是返回這將是我參考的真正實現大小)

所以我的問題其實是非常簡單的:

我們可以依靠sizeof操作時,它含有,具體而言,附圖成員返回一個類的實際內存佔用?

+6

你意識到採用碰巧是一個引用的變量的sizeof和帶有一個非靜態數據成員的* type *的sizeof是一個引用有很大的區別,對嗎? –

+2

我甚至都不明白這個問題。你問你是否可以依靠sizeof告訴你正確的大小?是。當然可以。 –

+0

你確實這樣做*因此,看來明天我可以想出我自己的參考實現,它需要200個字節並確保sizeof運算符返回正確的對象大小。*您必須使自己的編譯器正確嗎? – NathanOliver

回答

6

比較和對比:

struct container { 
    long double& dbl; 
}; 

std::cout << sizeof(container::dbl) << '\n'; 
std::cout << sizeof(container)  << '\n'; 

Live on ideone

一個行告訴你的引用的目標的大小。另一個告訴你包含參考的結構的大小。

這種行爲不是偶然的。它是由標準定義的,是的,你可以依靠它。

在這個問題背後似乎有一個假設,sizeof運算符與參考或引用類型的行爲在某種程度上是任意的和傳統的。事實並非如此;它與通常適用於參考文獻的邏輯不同。

如果非要

long double dbl; 

然後任何使用的在其範圍內dbl是左值,這是說一個參考。這是必要的,以便可以將值分配給dbl。所以dbl的類型(如例如decltype(dbl)所示)是long double&,而不是long double

如果sizeof(dbl)返回引用本身的大小而不是引用對象的大小,那將是荒謬的。

一旦將參考放入結構中,您就擁有了完全不同的野獸。 作爲對象的一部分,引用佔用空間,除非包含它的整個對象可以被優化,否則這些空間不能被優化。

+0

好的,非常清楚,正如Nicol先指出的那樣,我在類/結構類型的大小與參考變量的大小之間感到困惑。 Upvoted(+ Nicol's) – Romain227

+0

嗯,我認爲我完全得到它,但實際上沒有:爲什麼我們實際上必須做出這種區分? sizeof(包含ref的類)和sizeof(a ref)之間的關係? – Romain227

+0

這就是我所讀的所有東西:在ref變量的情況下(見我的例子),編譯器很容易使它完全消失(因此直接打印變量q),但是在其他一些(比我的更復雜)的情況下,它可能不得不跟蹤它,因此必須真的創建一個參考 – Romain227

0

如果你的問題,如果你可以依靠以下類型的sizeof

struct A 
{ 
    int& r; 
}; 

然後是 - 你可以在包含引用結構依靠sizeof

E.g.此代碼是安全的:

char* buffer = new char[sizeof(A)]; 
    int value; 
    A* valueRef = new (buffer) A{value}; 

您有足夠的字節緩衝區來存儲對象。

0
struct S { 
    long double& d; 
}; 

static_assert(sizeof(S::d) == sizeof(long double)); 
static_assert(sizeof(S) != sizeof(S::d)); // true on most platforms 

編譯器是足夠聰明,知道的S大小,它不感到困惑,並認爲這是sizeof(S::d)因爲那將是愚蠢的。