在实际中,使用const定义的栈变量,最终还是一个变量,只是在编译期间对语法进行了检查,发现代码有对const修饰的变量存在直接修改行为则报错.
被const修饰过的栈变量本质上是可以被修改的.我们可以利用指针获取const修饰过的栈变量的地址,强制将const属性修饰去掉,就可以修改对应的数据内容了,如以下代码
#includeint main() { const int n1 = 5; int* p = (int*)&n1; *p = 6; int n2 = n1; return 0; }
对应的反汇编 push ebp // mov ebp,esp // sub esp,0ch // 开辟栈帧 mov dword ptr[ebp-4],5 //n1 = 5 lea eax,[ebp-4] mov [ebp-8],eax //p = (int*)&n1 mov ecx,[ebp-8] mov dword ptr[ecx],6 //*p = 6 mov dword ptr[ebp-0ch],5 //n2 = n1 xor eax,eax mov esp,ebp pop ebp retn
在上述代码中,由于const修饰的变量n1被赋值一个数字常量5,编译器在编译过程中发现n1的初始值是可知的,并且被修饰为const.之后所有使用n1的地方都被替换为这个可预知的值,故
int n2 = n1;对应的汇编代码并没有将n1赋值给n2,而是用常量值5代替.如果n1初始化为一个未知的值则编译器不会做此优化
在上述代码实例中指针确实可以将n1的值修改成6
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)