const 疑惑合集

来源:互联网 发布:科创人才网络平台 编辑:程序博客网 时间:2024/04/29 18:59

1.const int a = 10;    

   const int *p1 = &a;

   const int *p2 =const_cast<int *>(p1);

   *p2 = 2;

   *p1, *p2是2了,为什么a 还是10? 但&a, *p1, *p1在输出的地址是相同的啊!

   

   a是const在编译的时候的值已经确定,为常量。用以下代码来说明为什么。

#include <stdio.h>void f(){   const int a = 10;   const int *p1 = &a;   int *p2 = const_cast<int *>(p1);   *p2 = 2;   int t = *p1 + *p2;   printf("%d %d", *p1, *p2);}

反汇编如下

.file"why_const_to_nonconst.cpp".section .rdata,"dr"LC0:.ascii "%d %d\0".text.globl __Z1fv.def__Z1fv;.scl2;.type32;.endef__Z1fv:LFB8:pushl%ebpLCFI0:movl%esp, %ebpLCFI1:subl$40, %espLCFI2:movl$1, -24(%ebp);   const int a = 1;leal-24(%ebp), %eax;movl%eax, -12(%ebp);   const int *p1 = &a;movl-12(%ebp), %eax;movl%eax, -16(%ebp);   int *p2 = const_cast<int *>(p1);movl-16(%ebp), %eax;movl$2, (%eax);   *p2 = 2;movl-12(%ebp), %eax;movl(%eax), %edx;get *p1movl-16(%ebp), %eax;movl(%eax), %eax;get *p2leal(%edx,%eax), %eax ;movl%eax, -20(%ebp)  ;   int t = *p1 + *p2;;; 以下是printf的传参数movl-16(%ebp), %eax  ;movl(%eax), %edx  ;get *p1movl-12(%ebp), %eax  ;movl(%eax), %eax  ;get *p2movl%edx, 8(%esp)  ;8(%esp) = *p1movl%eax, 4(%esp)  ;4(%esp) = *p2movl$LC0, (%esp)call_printfleaveLCFI3:retLFE8:.def_printf;.scl2;.type32;.endef
显然,p1,p1的值是相同的,即指向同一个位置。执行*p2 = 2, *p1,*p2就是2。

修改原来的代码如下,与上述代码进行对比。

#include <stdio.h>void f(){   const int a = 10;   const int *p1 = &a;   int *p2 = const_cast<int *>(p1);   *p2 = 2;   int t = *p1 + *p2 + a;//修改的代码   printf("%d %d", *p1, *p2);}

.file"why_const_to_nonconst.cpp".section .rdata,"dr"LC0:.ascii "%d %d\0".text.globl __Z1fv.def__Z1fv;.scl2;.type32;.endef__Z1fv:LFB8:pushl%ebpLCFI0:movl%esp, %ebpLCFI1:subl$40, %espLCFI2:movl$10, -24(%ebp)leal-24(%ebp), %eaxmovl%eax, -12(%ebp)movl-12(%ebp), %eaxmovl%eax, -16(%ebp)movl-16(%ebp), %eaxmovl$2, (%eax)movl-12(%ebp), %eaxmovl(%eax), %edxmovl-16(%ebp), %eaxmovl(%eax), %eaxleal(%edx,%eax), %eax ; tmp = *p1 + *p2addl$10, %eax; result = tmp + amovl%eax, -20(%ebp); int t = resultmovl-16(%ebp), %eaxmovl(%eax), %edxmovl-12(%ebp), %eaxmovl(%eax), %eaxmovl%edx, 8(%esp)movl%eax, 4(%esp)movl$LC0, (%esp)call_printfleaveLCFI3:retLFE8:.def_printf;.scl2;.type32;.endef

addl$10, %eax; result = tmp + a
可以看到a被直接用常量10代替, 由此可以看到编译器在编译时将const常量替换成“常量”。

 &a虽然是a的地址,如果&a这个盒子所存储的东西被修改了, 与a没有关系。因为在编译的时候a被替换成常量了,如上面的10。

由以上可以看到a在编译时已经被替换成真正的常量,&a位置和*p1和*p2是指向相同的地址的。