标签:
在c中const这个关键字,维基给出这样一句话
When applied in an object declaration,[b] it indicates that the object is a constant: its value does not change, unlike a variable. This basic use – to declare constants – has parallels in many other languages
实际就是用于不允许修改其值的,但是这里需要思考的就是,不允许修改的a的值还是内存里的值,如果非要修改内存里的值怎么办?cpu只认识0101,编译器是如何完成const的功能的,下面通过实验分析一下,(实验平台64位win7,vs2008)
初始代码
int main()
{
int b,c;
const int a=10;
c=1;
return 0;
}
很常见,如果
a=11;首先编译不通过,这是c语法就不允许的。
看看此时a对应的内存里面的值,
如果想修改一个值,还有一种方式就是指针间接完成。然后修改代码
int main()
{
int b,c;
const int a=10;
int *p=(int*)&a;
*p=11;
return 0;
}
编译通过,看看内存里的东西
的确被修改了,
也就是说,绕过编译器的const修饰规则,依旧可以修改这个内存的值。
这里就会有出现一个问题,修改之后,a也是指向的这个地址,但下次引用a时,难道a不从那个内存地址里面取值吗
比如下面这种情况
int main()
{
int b,c;
const int a=10;
int *p=(int*)&a;
*p=11;
c=1;
b=a+c;
return 0;
}
结果b的值为11,也就是说,编译器在计算a时,并没有从a所对应的内存中去取值。
那编译器是如何完成的。看看这段代码的汇编
int b,c;
const int a=10;
012E1F6E mov dword ptr [a],0Ah
int *p=(int*)&a;
012E1F75 lea eax,[a]
012E1F78 mov dword ptr [p],eax
*p=11;
012E1F7B mov eax,dword ptr [p]
012E1F7E mov dword ptr [eax],0Bh
c=1;
012E1F84 mov dword ptr [c],1
b=a+c;
012E1F8B mov eax,dword ptr [c]
012E1F8E add eax,0Ah
012E1F91 mov dword ptr [b],eax
return 0;
012E1F94 xor eax,eax
主要是这几句话
b=a+c;
012E1F8B mov eax,dword ptr [c]
012E1F8E add eax,0Ah
012E1F91 mov dword ptr [b],eax
在引用c的值的时候,是从c对应的内存中去去数据,然后赋值给寄存器eax,
但是在引用a变量时,并没有像c一样,而是直接用10来代替。
卧槽,这不就是宏定义么,直接将a用它初始化的值就行替换,
用一个对比实验
#define a_tmp (10)
int main()
{
int b,c;
const int a=10;
int *p=(int*)&a;
*p=11;
c=1;
b=a+c;
b=a_tmp+c;
return 0;
}
观察汇编代码
b=a+c;
01221F8B mov eax,dword ptr [c]
01221F8E add eax,0Ah
01221F91 mov dword ptr [b],eax
b=a_tmp+c;
01221F94 mov eax,dword ptr [c]
01221F97 add eax,0Ah
01221F9A mov dword ptr [b],eax
一模一样,这下就明白了。。。。。。。。。。
版权声明:本文为博主原创文章,未经博主允许不得转载。
分析编译器对C关键字的处理『跳过编译器的语法检查,完成很危险的操作』
标签:
原文地址:http://blog.csdn.net/u010442328/article/details/47259393