下面是《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: }