指针与引用(gcc如何实现引用的)
首先,变量名在编译成汇编语言的时候,会被翻译成地址。
例如 :
1 void square() { 2 int var = 0; 3 }
会被翻译成 :
1 square(): 2 push rbp 3 mov rbp, rsp 4 mov DWORD PTR [rbp-4], 0 5 nop 6 pop rbp 7 ret
rbp - 4 在这里就是变量名 var 翻译而成的,而 DWORD PTR [rbp - 4]就是变量值。
而指针类型的变量名也会翻译成地址,但是这个指针变量值也是一个地址。
1 void square() { 2 int var = 0; 3 int * pointer = &var; 4 }
会被翻译成 :
1 square(): 2 push rbp 3 mov rbp, rsp 4 mov DWORD PTR [rbp-12], 0 5 lea rax, [rbp-12] 6 mov QWORD PTR [rbp-8], rax 7 nop 8 pop rbp 9 ret
在这里, rbp-12就是变量名 var 翻译而成的。
int * pointer = &var;
被翻译成了
lea rax, [rbp-12]
mov QWORD PTR [rbp-8], rax
而指针变量名pointer 被翻译成 rbp - 8。 指针变量pointer 的值是 rbp-12。
引用与指针的区别在哪呢?
引用与变量名一样都是地址。
例如 :
1 void square() { 2 int var = 0; 3 int &ref = var; 4 int * pointer = &ref; 5 }
会被翻译成 :
1 square(): 2 push rbp 3 mov rbp, rsp 4 mov DWORD PTR [rbp-20], 0 5 lea rax, [rbp-20] 6 mov QWORD PTR [rbp-8], rax 7 mov rax, QWORD PTR [rbp-8] 8 mov QWORD PTR [rbp-16], rax 9 nop 10 pop rbp 11 ret
int * pointer = &ref;
被翻译成:
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rbp-16], rax
其中 rbp - 8是一个指针变量 &ref,而 [rbp - 8]的值是 rbp - 20, 在这里 QWORD PTR [rbp-8]其实就是引用ref也就是 rbp - 20。 而实现的具体方法就是利用指针变量 rbp-8来实现的。
所以创建引用所需要的内存等于指针变量所需要的内存(因为在gcc中是利用指针实现引用的)。在其他平台则不一定。
pass by reference (to const)
如若形参列表是引用形式,那么在gcc中会传入什么呢?
如下 : add函数。
1 int add (const int& a, const int& b){ 2 return a + b; 3 } 4 5 void test (){ 6 add(1,2); 7 }
会被翻译成 :
1 add(int const&, int const&): 2 push rbp 3 mov rbp, rsp 4 mov QWORD PTR [rbp-8], rdi 5 mov QWORD PTR [rbp-16], rsi 6 mov rax, QWORD PTR [rbp-8] 7 mov edx, DWORD PTR [rax] 8 mov rax, QWORD PTR [rbp-16] 9 mov eax, DWORD PTR [rax] 10 add eax, edx 11 pop rbp 12 ret 13 test(): 14 push rbp 15 mov rbp, rsp 16 sub rsp, 16 17 mov DWORD PTR [rbp-8], 2 18 mov DWORD PTR [rbp-4], 1 19 lea rdx, [rbp-8] 20 lea rax, [rbp-4] 21 mov rsi, rdx 22 mov rdi, rax 23 call add(int const&, int const&) 24 nop 25 leave 26 ret
在上述汇编代码中,rsi 和 rdi 是 add 函数的实参。而汇编代码中 17,18行表示1,2两个常量分别存储在test函数栈中 rbp - 4, rbp - 8 的位置。
汇编代码中 19,20,21,22行则利用 lea 指令将 rbp - 4, rbp - 8 的地址作为参数传入到 add 函数中去了。
所以 pass by reference (to const) 传入的是指针。
以上所有解释都基于 gcc 实现。