守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 1071|回复: 0

[C++] C++中对于const的理解

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51717
    钢镚
    1422

    开源英雄守望者

    发表于 2015-1-12 21:12:53 | 显示全部楼层 |阅读模式
    C++Primer中并没有对const过多的解析,只说明为是一个使变量不可修改的限定符.但是仅仅知道这点对于我来说是远远不够的,const是怎么做到的限制修改?谁在帮const做这个限制?编辑器是怎么实现不可修改的?在认识const之前 我知道C++中唯一不可修改的就是常量,例如:


    1. int i = 1000;
    复制代码

    这个1000就是常量,除了修改生成的文件之外 任何方式都无法修改这个1000 .(修改生成的文件是怎么修改?例如生成了exe可执行文件,直接定位到代码区 找到这个变量定义的地方 把 1000的字节码E8 03 00 00改了..).

    下面我们尝试下修改const声明的常量:

    1. void main()
    2. {
    3.     const int q = 1000;
    4.      printf("q1 = %d\r\n",q);
    5.      int *pQ = (int*)&q;
    6.      *pQ = 50;
    7.      printf("q2 = %d\r\n",q);
    8.      printf("pQ = %d\r\n",*pQ);
    9.      printf("q address:%d\r\n",&q);
    10.      printf("pQ address:%d\r\n",pQ);
    11.     getchar();
    12. }
    复制代码

    这段代码编译运行后输出:

    1. q1 = 1000
    2. q2 = 1000
    3. pQ = 50
    4. q address:1702152
    5. pQ address:1702152
    复制代码

    显然 const 常量 q 前后输出的都是1000.而q的指针修改后输出的是50.q的地址和pQ所指向的地址一样,输出的内容却不一样.这就让人奇怪了.按道理说 同一块内存(1702152) 改变了值之后所输出的内容应该也都是一样的(50)才对. 我们反编译看看编译器都做了什么:

    1.     const int q = 1000;
    2. 002C35EE  mov         dword ptr [q],3E8h  
    3.      printf("q1 = %d\r\n",q);
    4. 002C35F5  mov         esi,esp  
    5. 002C35F7  push        3E8h  
    6. 002C35FC  push        2CCC90h  
    7. 002C3601  call        dword ptr ds:[2D045Ch]  
    8. 002C3607  add         esp,8  
    9. 002C360A  cmp         esi,esp  
    10. 002C360C  call        __RTC_CheckEsp (02C1325h)  
    11.      int *pQ = (int*)&q;
    12. 002C3611  lea         eax,[q]  
    13. 002C3614  mov         dword ptr [pQ],eax  
    14.      *pQ = 50;
    15. 002C3617  mov         eax,dword ptr [pQ]  
    16. 002C361A  mov         dword ptr [eax],32h  
    17.      printf("q2 = %d\r\n",q);
    18. 002C3620  mov         esi,esp  
    19. 002C3622  push        3E8h  
    20. 002C3627  push        2CCCDCh  
    21. 002C362C  call        dword ptr ds:[2D045Ch]  
    22. 002C3632  add         esp,8  
    23. 002C3635  cmp         esi,esp  
    24. 002C3637  call        __RTC_CheckEsp (02C1325h)  
    25.      printf("pQ = %d\r\n",*pQ);
    26. 002C363C  mov         esi,esp  
    27. 002C363E  mov         eax,dword ptr [pQ]  
    28. 002C3641  mov         ecx,dword ptr [eax]  
    29. 002C3643  push        ecx  
    30. 002C3644  push        2CDAB8h  
    31. 002C3649  call        dword ptr ds:[2D045Ch]  
    32. 002C364F  add         esp,8  
    33. 002C3652  cmp         esi,esp  
    34. 002C3654  call        __RTC_CheckEsp (02C1325h)  
    35.      printf("q address:%d\r\n",&q);
    36. 002C3659  mov         esi,esp  
    37. 002C365B  lea         eax,[q]  
    38. 002C365E  push        eax  
    39. 002C365F  push        2CCC70h  
    40. 002C3664  call        dword ptr ds:[2D045Ch]  
    41. 002C366A  add         esp,8  
    42. 002C366D  cmp         esi,esp  
    43. 002C366F  call        __RTC_CheckEsp (02C1325h)  
    44.      printf("pQ address:%d\r\n",pQ);
    45. 002C3674  mov         esi,esp  
    46. 002C3676  mov         eax,dword ptr [pQ]  
    47. 002C3679  push        eax  
    48. 002C367A  push        2CDAC4h  
    49. 002C367F  call        dword ptr ds:[2D045Ch]  
    50. 002C3685  add         esp,8  
    51. 002C3688  cmp         esi,esp  
    52. 002C368A  call        __RTC_CheckEsp (02C1325h)  
    复制代码

    注:3E8h = 1000,32h = 50

    由上面汇编代码可以看出.编译器把代码中的所有q都用3E8H代替了.也就是说 const定义的常量 在编译器生成阶段被替换成真实值了.所以无论你怎么修改const变量名所指的内存,其实都是没有用处的.因为在程序生成之后 所有的q 都被替换了.即使你在你的IDE编辑器中调试的时候看到q所指的是修改后的值50.


    本文来自:http://shadowkong.com/archives/1845


    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2019-9-15 14:11 , Processed in 0.039332 second(s), 32 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表