[英]How do instruction sets differentiate value from reference
讓我們看一下這段代碼:
int main ()
{
int a = 5;
int&b = a;
cout << a << endl; // 5 is displayed
cout << b << endl; // 5 is also displayed
return 0;
}
這是我在調試器中看到的行為。
int a = 5
將在內存地址-0x14(%rbp)中分配值5
int& b = a
將分配值-0x14(%rbp)
在存儲器地址-0x8(%RBP)
當我cout << a << endl
,將顯示a地址(即-0x14(%rbp))中的值。
但是以某種方式,當我執行cout << b << endl
,確定b地址中的值(即-0x8(%rbp)
)是一個地址,然后顯示該地址的值( -0x14(%rbp)
) 。
這是std :: cout調用的程序集:
20 cout << a << endl;
0000000000401506: mov -0xc(%rbp),%eax
0000000000401509: mov %eax,%edx
000000000040150b: lea 0x6f8c9c6e(%rip),%rcx # 0x6fccb180 <libstdc++-6!_ZSt4cout>
0000000000401512: callq 0x4015f8 <_ZNSolsEi>
0000000000401517: lea 0xe2(%rip),%rdx # 0x401600 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_>
000000000040151e: mov %rax,%rcx
0000000000401521: callq 0x401608 <_ZNSolsEPFRSoS_E>
21 cout << b << endl;
0000000000401526: mov -0x8(%rbp),%rax
000000000040152a: mov (%rax),%eax
000000000040152c: mov %eax,%edx
000000000040152e: lea 0x6f8c9c4b(%rip),%rcx # 0x6fccb180 <libstdc++-6!_ZSt4cout>
0000000000401535: callq 0x4015f8 <_ZNSolsEi>
000000000040153a: lea 0xbf(%rip),%rdx # 0x401600 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_>
0000000000401541: mov %rax,%rcx
0000000000401544: callq 0x401608 <_ZNSolsEPFRSoS_E>
24 return 0;
題:
兩條std :: cout指令都非常相似, a
與b
有何區別?
簡而言之:事實並非如此。
CPU本身並不關心哪種類型存儲在哪里,它只執行編譯器生成的指令。
編譯器知道b
是一個引用,而不是int
。 因此,它指示CPU將b
視為指針。
如果查看程序的匯編代碼,則會看到訪問a
和b
的指令是不同的: b
的部分包含一條額外的指令。
mov (%rax),%eax
這是取消引用的步驟。 (在該匯編符號中,括號表示取消引用,因此此指令含義類似於eax = * rax)。
我想您絕對沒有要求優化。 盡管即使那樣,我仍希望訪問a
和b
來生成完全相同的代碼(至少在這種情況下)。
關於編譯器如何知道: a
和b
具有不同的類型,因此編譯器知道對它們執行不同的操作。 該標准經過精心設計,可以用int&
int* const
替換int&
,然后在每次訪問時自動取消引用(初始化除外)將產生符合要求的實現; 看起來這就是您的編譯器正在執行的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.