C++中对于const的理解

C++Primer中并没有对const过多的解析,只说明为是一个使变量不可修改的限定符.但是仅仅知道这点对于我来说是远远不够的,const是怎么做到的限制修改?谁在帮const做这个限制?编辑器是怎么实现不可修改的?在认识const之前 我知道C++中唯一不可修改的就是常量,例如:

int i = 1000;

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

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

void main()
{
    const int q = 1000;
     printf("q1 = %d\r\n",q);
     int *pQ = (int*)&q;
     *pQ = 50;
     printf("q2 = %d\r\n",q);
     printf("pQ = %d\r\n",*pQ);
     printf("q address:%d\r\n",&q);
     printf("pQ address:%d\r\n",pQ);
    getchar();
}

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

q1 = 1000
q2 = 1000
pQ = 50
q address:1702152
pQ address:1702152

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

     const int q = 1000;
002C35EE  mov         dword ptr [q],3E8h  
     printf("q1 = %d\r\n",q);
002C35F5  mov         esi,esp  
002C35F7  push        3E8h  
002C35FC  push        2CCC90h  
002C3601  call        dword ptr ds:[2D045Ch]  
002C3607  add         esp,8  
002C360A  cmp         esi,esp  
002C360C  call        __RTC_CheckEsp (02C1325h)  
     int *pQ = (int*)&q;
002C3611  lea         eax,[q]  
002C3614  mov         dword ptr [pQ],eax  
     *pQ = 50;
002C3617  mov         eax,dword ptr [pQ]  
002C361A  mov         dword ptr [eax],32h  
     printf("q2 = %d\r\n",q);
002C3620  mov         esi,esp  
002C3622  push        3E8h  
002C3627  push        2CCCDCh  
002C362C  call        dword ptr ds:[2D045Ch]  
002C3632  add         esp,8  
002C3635  cmp         esi,esp  
002C3637  call        __RTC_CheckEsp (02C1325h)  
     printf("pQ = %d\r\n",*pQ);
002C363C  mov         esi,esp  
002C363E  mov         eax,dword ptr [pQ]  
002C3641  mov         ecx,dword ptr [eax]  
002C3643  push        ecx  
002C3644  push        2CDAB8h  
002C3649  call        dword ptr ds:[2D045Ch]  
002C364F  add         esp,8  
002C3652  cmp         esi,esp  
002C3654  call        __RTC_CheckEsp (02C1325h)  
     printf("q address:%d\r\n",&q);
002C3659  mov         esi,esp  
002C365B  lea         eax,[q]  
002C365E  push        eax  
002C365F  push        2CCC70h  
002C3664  call        dword ptr ds:[2D045Ch]  
002C366A  add         esp,8  
002C366D  cmp         esi,esp  
002C366F  call        __RTC_CheckEsp (02C1325h)  
     printf("pQ address:%d\r\n",pQ);
002C3674  mov         esi,esp  
002C3676  mov         eax,dword ptr [pQ]  
002C3679  push        eax  
002C367A  push        2CDAC4h  
002C367F  call        dword ptr ds:[2D045Ch]  
002C3685  add         esp,8  
002C3688  cmp         esi,esp  
002C368A  call        __RTC_CheckEsp (02C1325h)  

注:3E8h = 1000,32h = 50

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

《C++中对于const的理解》有一个想法

破晓进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注