小步慢跑

 

编译器对const的优化

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

posted on 2012-08-01 17:57 zaccheo 阅读(721) 评论(0)  编辑 收藏 引用 所属分类: 内功


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿

随笔分类(23)

随笔档案(26)

文章分类(1)

文章档案(1)

csdn

搜索

最新评论

阅读排行榜

评论排行榜