下面是《DRE》這本書中討論const和define的差別時的一個小例子(vc6)
1: #include <iostream>
2: using namespace std;
3: void main()
4: {
5: const int nConst = 5;
6:
7: int * pConst = (int*)&nConst;
8: *pConst = 6;
9:
10: int nVar = nConst;
11: cout <<"nConst: " <<nConst<<" nVar:"<<nVar<<endl;
12: getchar();
13: }
本以為nConst的內容已經被修改為6了,最后 nVar和nConst都應該是6,可是運行的輸出都是 5。大為不解。先單步,發現在 執行int nVar = nConst前,nConst的值確實是6,可是執行后,nVar的值卻是5。這下更是不解了。再看反匯編:
1: 5: const int nConst = 5;
2: 00401588 mov dword ptr [ebp-4],5
3: 6:
4: 7: int * pConst = (int*)&nConst;
5: 0040158F lea eax,[ebp-4]
6: 00401592 mov dword ptr [ebp-8],eax
7: 8: *pConst = 6;
8: 00401595 mov ecx,dword ptr [ebp-8]
9: 00401598 mov dword ptr [ecx],6
10: 9:
11: 10: int nVar = nConst;
12: 0040159E mov dword ptr [ebp-0Ch],5
13: 11: cout <<"nConst: " <<nConst<<" nVar:"<<nVar<<endl;
可以看到 int nVar = nConst 這行對應的匯編 是直接把 5 賦給了 nVar。cout<<時也是如此。
《DRE》書中的解釋如下:“由于 const 修飾的變量 nConst 被賦值一個數字常量5,編譯器在編譯過程中發現 nConst的初值是可知的,并且被修飾為const。之后所有使用nConst的地方都以這個可預知值替換,故 int nVar = nConst; 對應的會變代碼沒有將nConst賦值給nVar,而是用常量5代替,如果nConst的值為一個未知值,那么編譯器將不會作此優化”
試著將上面的代碼修改如下,輸出就都是6 了
1: #include <iostream>
2: using namespace std;
3: void main()
4: {
5: int nTemp = 5;
6: const int nConst = nTemp;
7:
8: int * pConst = (int*)&nConst;
9: *pConst = 6;
10:
11: int nVar = nConst;
12: cout <<"nConst: " <<nConst<<" nVar:"<<nVar<<endl;
13: getchar();
14: }