- 論壇徽章:
- 2
|
引用不占空間的說法是流傳很廣的誤會(huì)…… 造成該誤會(huì)的原因可能有:
1. 自動(dòng)變量?jī)?yōu)化
int是否占用空間? 這個(gè)不好說, 但int能sizeof, 能用 & 取到地址(非register)是肯定的。
- int f(int x, int y) {
- int xx = x*x;
- int yy = y*y;
- int a = xx + yy;
- return a;
- }
復(fù)制代碼 xx,yy,a是否占空間? 優(yōu)化開高了也許就不占了, 直接寄存器干活。
x/y是否占空間? 至少i386上 cdecl 調(diào)用約定是占的。
2. 無法取得變量本身的地址
sizeof得到的是被引用對(duì)象的大小, & 得到的是被引用對(duì)象的地址。
因?yàn)橐谜Z意的關(guān)系, 沒辦法"直接"獲得引用變量本身的大小與地址信息
可能也造成了該誤會(huì)……
類似Windows下的dll導(dǎo)入機(jī)制:
- __declspec(dllimport) double x;
復(fù)制代碼 實(shí)際上類似這樣的代碼
- extern double* __imp_x;
- #define x (*__imp_x);
復(fù)制代碼 通過x宏, 沒法取得 __imp_x 的大小與地址。
C++沒有規(guī)定引用如何實(shí)現(xiàn)。 但在i386上, cl/gcc/clang實(shí)現(xiàn)都類似這樣。
3. 繞過語法糖干擾
最簡(jiǎn)單的方法:
- struct X { double& d; };
- enum { size = sizeof(X) }; // 該平臺(tái)上引用大小
- double d;
- X x = { d };
- void* address = &x; // 引用變量的地址
- unsigned char representation[sizeof(X)];
- memcpy(representation, address, sizeof x); // 可查看引用變量的表示
復(fù)制代碼 其他還有很多方法阻止編譯器優(yōu)化, 比如參數(shù), 靜態(tài)變量…… 不過都比結(jié)構(gòu)體復(fù)雜。
4. 小結(jié)
C++ (印象中)沒有詳細(xì)描述引用變量的實(shí)現(xiàn)方式。
但在 i386(cl/gcc/clang) 下, 引用 —— 如同 int —— 是有大小的, 可以用 3 的方式得到
自動(dòng)變量的空間(無論是否是引用)都有可能被優(yōu)化。 |
|