今天有朋友又問我一個關於引用指針的問題:
const int a=4;
const int *pi = &a;
const int *&ri = pi; // ok const int *&ri = &a error
他說為甚麼 const int *&ri = &a會出現錯誤,而const int *&ri = pi卻可以通過編譯.ri不也是一個指針嘛,它為甚麼不能夠接收a變量的地址呢?
其實我們只要將上述代碼反彙編,就可以知道原因了.
4: const int *pi = &a;
0040102F lea eax,[ebp-4]
00401032 mov dword ptr [ebp-8],eax
5: const int *&ri = pi;
00401035 lea ecx,[ebp-8]
00401038 mov dword ptr [ebp-0Ch],ecx
上面是我在VC中得到的彙編碼.第六行清楚地說明保存在ri中的其實是一個指向a變量的指針的地址,而不是我們想像當中的a變量的地址.所以一旦我們使用const int *pi = &a這條語句給引用指針賦值,那麼編譯器轉出的彙編碼就會先將a變量的地址保存在某個寄存器中,然後再把寄存器的地址傳給ri這個引用指針.這些操作你是否發現了甚麼不妥之處?對了,寄存器的地址是不能夠被直接被使用的,所以編譯器就不可能產生那條語句的目標碼,自然要報錯啦.