引用的實現實質上跟指針是一樣的,如下:
//------------------------------------------------
#include <iostream>
using namespace std;
int main()
{
int a = 3;
int &ref_a = a;
ref_a += 2;
return 0;
}
//-----------------------------------------------
1: #include <iostream>
2:
3: using namespace std;
4:
5: int main()
6: {
00401030 55 push ebp
00401031 8B EC mov ebp,esp
00401033 83 EC 48 sub esp,48h
00401036 53 push ebx
00401037 56 push esi
00401038 57 push edi
00401039 8D 7D B8 lea edi,[ebp-48h]
0040103C B9 12 00 00 00 mov ecx,12h
00401041 B8 CC CC CC CC mov eax,0CCCCCCCCh
00401046 F3 AB rep stos dword ptr [edi]
7: int a = 3;
00401048 C7 45 FC 03 00 00 00 mov dword ptr [ebp-4],3 ; a存儲在內存中的[ebp-4]處,初值爲3
8: int &ref_a = a;
0040104F 8D 45 FC lea eax,[ebp-4] ; 取[ebp-4]地址給eax,(ref_a = &a)
00401052 89 45 F8 mov dword ptr [ebp-8],eax ; 將此地址值保存在[ebp-8]處,作爲ref_a的內容(也就是其所指向的變量的地址)
9:
10: ref_a += 2;
00401055 8B 4D F8 mov ecx,dword ptr [ebp-8] ; 地址賦給ecx
00401058 8B 11 mov edx,dword ptr [ecx] ; 取ecx中保存的地址處的值賦給edx(也就是a的值)
0040105A 83 C2 02 add edx,2 ; 加2
0040105D 8B 45 F8 mov eax,dword ptr [ebp-8] ; 將a的地址賦給eax (eax = &a)
00401060 89 10 mov dword ptr [eax],edx ; 把計算結果保存到a的地址空間處,實現了對a的改變
11: return 0;
00401062 33 C0 xor eax,eax
12: }
---------------------------------------------
觀察宏的反彙編代碼
//---------------------------------------------
#include <stdio.h>
#define CMP(x,y) ( (x) > (y) ? 1 : -1)
int main()
{
int r = CMP(2,1+2);
printf("%d/n", r);
return 0;
}
//-----------------------------------------------
$gcc -O2 -S macro_disasm.c
GCC優化編譯後:
.file "macro_disasm.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
LC0:
.ascii "%d/12/0"
.p2align 2
.globl _main
_main:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
addl $-8,%esp
pushl $-1 ; 居然直接在彙編代碼中顯示結果-1
pushl $LC0
call _printf
xorl %eax,%eax
movl %ebp,%esp
popl %ebp
ret
$gcc -S macro_disasm.c
不用優化編譯:
.file "macro_disasm.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
LC0:
.ascii "%d/12/0"
.p2align 2
.globl _main
_main:
pushl %ebp
movl %esp,%ebp
subl $24,%esp
movl $-1,-4(%ebp) ; 仍然直接將結果-1放入內存
addl $-8,%esp
movl -4(%ebp),%eax ; 讀出結果-1,進棧
pushl %eax
pushl $LC0
call _printf
addl $16,%esp
xorl %eax,%eax
jmp L2
.p2align 4,,7
L2:
movl %ebp,%esp
popl %ebp
ret
宏在編譯過程中就被編譯器直接替換,不生成額外的執行代碼。