const 实现

const 实现

const仅对编译器有效。
严格来说,const不是“不可修改”,而是告诉编译器:我的程序不应该去修改。
如果编译器发现程序企图修改这个变量,就会报错。

至于隐式的修改,一般是由于一些不规范的代码引起的(如char * p = "abcde")。有的编译器把常量放入只读内存页,只要修改,硬件就会报一个异常,导致程序崩溃。但是有些编译器不会把他们放入只读内存页,这种情况下什么错误都不会遇到,除了忽然发现程序出现许多意想不到的错误而永远找不到原因。

在代码中,对简单类型的对象可能会 直接优化成立即数

const int j=100;   
int *p=const_cast(&j);   
*p=200;   
cout<<
输出为什么是100呢?

cout<<*p<

编译器在优化代码时把cout<<<100了,所以虽然p和&j的值一样,但cout<

这是因为,const型在压栈时,是使用的直接的数,就有点像C的#define a 100

对于非系统缺省类型,系统不知道怎么去直接替换,因此必须占据内存。

 

-------------------------------

代码:

#include
using namespace std;

struct A
{
    int i;
    char ch;
    A()
    {
        i = 100;
        ch = 'S';
    }
};

int main()
{
    const A a;
    const int i = 200;
    int *p1 = (int*)&a.i;
    int *p2 = (int*)&i;

    *p1 = 1;
    *p2 = 2;
//    a.i = 200; //报错,左值不能为const
    cout << a.i << " " << a.ch << endl;
    cout << i << endl;
   return 0;
}

运行结果:

1 S
200

内存:

0012FF74  02 00 00 00 01 00  ......     ;i的值已经被修改为2(未修改前是200),a.i的值被修改为1(未修改前是100)
0012FF7A  00 00 53 CC CC CC  ..S烫.     ;53是字符'S'

内存的值被修改而结果中却没有显示出来,因为const int类型被编译器优化为立即数,而结构体A编译器优化不了……

反汇编代码:

19:       const A a;
00401598 8D 4D F8             lea         ecx,[ebp-8]
0040159B E8 DC FB FF FF       call        @ILT+375(A::A) (0040117c)
20:       const int i = 200;
004015A0 C7 45 F4 C8 00 00 00 mov         dword ptr [ebp-0Ch],0C8h
21:       int *p1 = (int*)&a.i;
004015A7 8D 45 F8             lea         eax,[ebp-8]
004015AA 89 45 F0             mov         dword ptr [ebp-10h],eax
22:       int *p2 = (int*)&i;
004015AD 8D 4D F4             lea         ecx,[ebp-0Ch]
004015B0 89 4D EC             mov         dword ptr [ebp-14h],ecx
23:
24:       *p1 = 1;
004015B3 8B 55 F0             mov         edx,dword ptr [ebp-10h]
004015B6 C7 02 01 00 00 00    mov         dword ptr [edx],1
25:       *p2 = 2;
004015BC 8B 45 EC             mov         eax,dword ptr [ebp-14h]
004015BF C7 00 02 00 00 00    mov         dword ptr [eax],2
26:   //  a.i = 200;
27:       cout << a.i << " " << a.ch << endl;
004015C5 68 C8 10 40 00       push        offset @ILT+195(std::endl) (004010c8)
004015CA 8A 4D FC             mov         cl,byte ptr [ebp-4]
004015CD 51                   push        ecx
004015CE 68 1C C0 46 00       push        offset string " " (0046c01c)
004015D3 8B 55 F8             mov         edx,dword ptr [ebp-8]
004015D6 52                   push        edx
004015D7 B9 E0 77 47 00       mov         ecx,offset std::cout (004777e0)
004015DC E8 1E FB FF FF       call        @ILT+250(std::basic_ostream >::operator<<) (004010ff)
004015E1 50                   push        eax
004015E2 E8 A8 FC FF FF       call        @ILT+650(std::operator<<) (0040128f)
004015E7 83 C4 08             add         esp,8
004015EA 50                   push        eax
004015EB E8 D2 FB FF FF       call        @ILT+445(std::operator<<) (004011c2)
004015F0 83 C4 08             add         esp,8
004015F3 8B C8                mov         ecx,eax
004015F5 E8 F0 FB FF FF       call        @ILT+485(std::basic_ostream >::operator<<) (004011ea)
28:       cout << i << endl;
004015FA 68 C8 10 40 00       push        offset @ILT+195(std::endl) (004010c8)
004015FF 68 C8 00 00 00       push        0C8h
00401604 B9 E0 77 47 00       mov         ecx,offset std::cout (004777e0)
00401609 E8 F1 FA FF FF       call        @ILT+250(std::basic_ostream >::operator<<) (004010ff)
0040160E 8B C8                mov         ecx,eax
00401610 E8 D5 FB FF FF       call        @ILT+485(std::basic_ostream >::operator<<) (004011ea)

 

-------------参考--------------

 

http://dev.chinaitzhe.com/c/2008-09/1222078066109523.html

 

http://forum.eviloctal.com/thread-39463-1-1.html (除了const的还有static,等有空了解一下……)

 

http://www.diybl.com/course/3_program/c++/cppjs/20091112/182222.html (有一些以前没注意到的const细节)

 

-------------------------------

忘了是在哪篇面经里看到一个问题:
java的const(貌似是final,对java不了解,汗)和c++的const各是怎么实现的?要不就是它们的区别是什么?(忘了是不是这样的问题)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值