首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C++ 关于const的有关问题

2013-03-12 
C++ 关于const的问题int main(){const int i 100const int *p &iint *q (int *)p*q 200cout

C++ 关于const的问题
int main()
{
    const int i = 100;
    const int *p = &i;
    int *q = (int *)p;
    *q = 200;
    cout<<*q<<"  "<<i<<endl;
    cout<<q<<"  "<<&i<<endl;
    cout<<*q<<"  "<<*p<<"  "<<*(&i)<<endl;
    return 0;
}

打印出来的值出人意料:
200  100
0012FF60  0012FF60
200  200  100

根据*p和*q的值看,i的值应该被改成200了,为什么打印出来的i值还是100。为了防止i是从寄存器取出来的,使用*(&i)读内存中的值也还是100。同一块内存地址读出来的数据怎么不一样?
[解决办法]
对,很可能是编译器优化的结果。
[解决办法]
在未优化编译的情况下,对于拥有const属性的i,编译器虽然为i分配了空间,但使用时,除非必要(比如取地址),是直接取其值100。
*(&i)被简化为i后,就直接取其值100用于cout输出了,
具体可参考下汇编源码

[解决办法]
我把你的程序简化了一下
intmain()
{
const int i = 100;
const int *p = &i;
int *q = (int *)p;
*q = 200;
//cout<<*q<<"  "<<i<<endl;
//cout<<q<<"  "<<&i<<endl;
cout<<*q<<"  "<<*p<<"  "<<*(&i)<<endl;

return0;
}

下面是对应的汇编代码,未优化
_main:
  00000000: 55                 push        ebp
  00000001: 8B EC              mov         ebp,esp
  00000003: 83 EC 0C           sub         esp,0Ch
  00000006: C7 45 F4 64 00 00  mov         dword ptr [ebp-0Ch],64h //这里为i分配空间并赋值100
            00
  0000000D: 8D 45 F4           lea         eax,[ebp-0Ch]
  00000010: 89 45 FC           mov         dword ptr [ebp-4],eax
  00000013: 8B 4D FC           mov         ecx,dword ptr [ebp-4]
  00000016: 89 4D F8           mov         dword ptr [ebp-8],ecx
  00000019: 8B 55 F8           mov         edx,dword ptr [ebp-8]
  0000001C: C7 02 C8 00 00 00  mov         dword ptr [edx],0C8h
  00000022: 68 00 00 00 00     push        offset ?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z


  00000027: 6A 64              push        64h    //这里直接将i也就是100亚入堆栈
  00000029: 68 00 00 00 00     push        offset $SG40957
  0000002E: 8B 45 FC           mov         eax,dword ptr [ebp-4]
  00000031: 8B 08              mov         ecx,dword ptr [eax]
  00000033: 51                 push        ecx
  00000034: 68 00 00 00 00     push        offset $SG40958
  00000039: 8B 55 F8           mov         edx,dword ptr [ebp-8]
  0000003C: 8B 02              mov         eax,dword ptr [edx]
  0000003E: 50                 push        eax
  0000003F: B9 00 00 00 00     mov         ecx,offset ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
  00000044: E8 00 00 00 00     call        ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z
  00000049: 50                 push        eax
  0000004A: E8 00 00 00 00     call        ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
  0000004F: 83 C4 08           add         esp,8
  00000052: 8B C8              mov         ecx,eax
  00000054: E8 00 00 00 00     call        ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z
  00000059: 50                 push        eax
  0000005A: E8 00 00 00 00     call        ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
  0000005F: 83 C4 08           add         esp,8
  00000062: 8B C8              mov         ecx,eax
  00000064: E8 00 00 00 00     call        ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z


  00000069: 8B C8              mov         ecx,eax
  0000006B: E8 00 00 00 00     call        ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z
  00000070: 33 C0              xor         eax,eax
  00000072: 8B E5              mov         esp,ebp
  00000074: 5D                 pop         ebp
  00000075: C3                 ret


注意00000027:这一行,是直接push 64h,而没有提取程序为i分配的空间[ebp-0ch]的值


[解决办法]
编译器知道const的哪些地方的用法,会对其进行优化。

const int i = 100;
cout << i << endl; // 在这里用,直接用100代替
cout << *(&i) << endl; // 在这里有使用,也直接用100代替

另外C++当中不提倡int *p = (int*)q这种转换,int *p = const_cast<int*>(q),会好看一点。
[解决办法]
另外简单的变量,表达式之类的,有时也会优化掉

int add(int x,int y)
{
   int z=x+y;
   return z;
}
int main(){
int x=10;
int y=100; 
printf("%d",add(x,y));

return 0;
}
会变成
int main(){

printf("%d",110);//这个优化叫常量代换。

return 0;
}


热点排行